Index: 运维集控/项目测试/运维标准版/reports/report_20250114_175101.html =================================================================== diff --git a/运维集控/项目测试/运维标准版/reports/report_20250114_175101.html b/运维集控/项目测试/运维标准版/reports/report_20250114_175101.html deleted file mode 100644 --- a/运维集控/项目测试/运维标准版/reports/report_20250114_175101.html (revision 1114284965c773bf063d20e1486fe7c5aa398274) +++ /dev/null (revision 1114284965c773bf063d20e1486fe7c5aa398274) @@ -1,2057 +0,0 @@ -<!DOCTYPE html> -<html> - <head> - <title>运维系统测试报告</title> - <meta charset="UTF-8"> - <style>body { - font-family: consolas, Verdana, sans-serif; - font-size: .95em; - 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; -}</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"); -}); - - - -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="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/01/14 17:51:01</td> - </tr> - <tr> - <td>结束时间</td> - <td>2025/01/14 17:51:47</td> - </tr> - <tr> - <td>耗时</td> - <td>46.602 秒</td> - </tr> - <tr> - <td>预备执行用例数量</td> - <td>51</td> - </tr> - <tr> - <td>实际执用例行数量</td> - <td>18</td> - </tr> - <tr> - <td>通过</td> - <td>5</td> - </tr> - <tr> - <td>失败</td> - <td style="color:red">3</td> - </tr> - <tr> - <td>异常</td> - <td style="color:red">10</td> - </tr> - <tr> - <td>阻塞</td> - <td style="color:red">33</td> - </tr> - <tr> - <td>套件初始化失败</td> - <td style="color:red">3</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>用例通过 9.8% : 5 个</span> - <div class="barchart_barbox"> - <div class="barchart_bar" style="width: 9.8%; background-color: #04AA6D;"></div> - </div> - </div> - <div class="barchar_item"> - <span>用例失败 5.9% : 3 个</span> - <div class="barchart_barbox"> - <div class="barchart_bar" style="width: 5.9%; background-color: #bb4069;"></div> - </div> - </div> - <div class="barchar_item"> - <span>用例异常 19.6% : 10 个</span> - <div class="barchart_barbox"> - <div class="barchart_bar" style="width: 19.6%; background-color: #9c27b0;"></div> - </div> - </div> - <div class="barchar_item"> - <span>用例阻塞 64.7% : 33 个</span> - <div class="barchart_barbox"> - <div class="barchart_bar" style="width: 64.7%; 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-01-14 17:51:01</span> - </div> - <div class="folder_body"> - <div class="info">打开默认浏览器</div> - </div> - </div> - </div> - <div class="suite_file" id="suite_file cases\01登录模块\管理员登录.py"> - <div> - <span class="label">进入文件</span> - <span>cases\01登录模块\管理员登录.py</span> - </div> - <div class="case pass" id="case_00000001"> - <div class="folder_header"> - <span class="label caselabel">用例 PASS</span> - <span class="casename">用户登录-001-登录账号为空</span> - <span class="executetime">2025-01-14 17:51:08</span> - </div> - <div class="folder_body"> - <span class="case_class_path">cases\01登录模块\管理员登录.py::User_Login</span> - <div class="test_steps" id="test_steps 用户登录-001-登录账号为空"> - <span class="label">测试步骤</span> - <div class="case_step"> - <span class="tag">步骤 #1</span> - <span> 用户登录测试</span> - </div> - <div class="info">输入登录账号: </div> - <div class="info">输入登录密码: ub@1234567</div> - <div class="info">输入验证码:csba</div> - <div class="info">点击登录按钮</div> - <div class="case_step"> - <span class="tag">步骤 #2</span> - <span>预期提示内容为:请输入登录账号</span> - </div> - <div class="case_step"> - <span class="tag">步骤 #3</span> - <span>获取登录提示内容</span> - </div> - <div class="checkpoint_pass"> - <span class="tag">检查点 PASS</span> - <span>校验提示内容是否跟预定结果一致</span> - </div> - <div> - <img class="screenshot" src="imgs/20250114175110392772.png" width="50%"> - </div> - </div> - </div> - </div> - <div class="case fail" id="case_00000002"> - <div class="folder_header"> - <span class="label caselabel">用例 FAIL</span> - <span class="casename">用户登录-002-登录密码为空</span> - <span class="executetime">2025-01-14 17:51:10</span> - </div> - <div class="folder_body"> - <span class="case_class_path">cases\01登录模块\管理员登录.py::User_Login</span> - <div class="test_steps" id="test_steps 用户登录-002-登录密码为空"> - <span class="label">测试步骤</span> - <div class="case_step"> - <span class="tag">步骤 #1</span> - <span>test_user3 用户登录测试</span> - </div> - <div class="info">输入登录账号: test_user3</div> - <div class="info">输入登录密码: </div> - <div class="info">输入验证码:csba</div> - <div class="info">点击登录按钮</div> - <div class="case_step"> - <span class="tag">步骤 #2</span> - <span>预期提示内容为:请输入登录密码</span> - </div> - <div class="case_step"> - <span class="tag">步骤 #3</span> - <span>获取登录提示内容</span> - </div> - <div class="checkpoint_fail"> - <span class="tag">检查点 FAIL</span> - <span>校验提示内容是否跟预定结果一致</span> - </div> - <div class="info error-info"> -Traceback: - File "D:\GithubData\自动化\ubains-module-test\运维集控\项目测试\运维标准版\cases\01登录模块\管理员登录.py", line 39, in teststeps - CHECK_POINT('校验提示内容是否跟预定结果一致', get_text == info)</div> - </div> - </div> - </div> - <div class="case pass" id="case_00000003"> - <div class="folder_header"> - <span class="label caselabel">用例 PASS</span> - <span class="casename">用户登录-003-验证码为空</span> - <span class="executetime">2025-01-14 17:51:13</span> - </div> - <div class="folder_body"> - <span class="case_class_path">cases\01登录模块\管理员登录.py::User_Login</span> - <div class="test_steps" id="test_steps 用户登录-003-验证码为空"> - <span class="label">测试步骤</span> - <div class="case_step"> - <span class="tag">步骤 #1</span> - <span>test_user4 用户登录测试</span> - </div> - <div class="info">输入登录账号: test_user4</div> - <div class="info">输入登录密码: ub@1234567</div> - <div class="info">输入验证码:</div> - <div class="info">点击登录按钮</div> - <div class="case_step"> - <span class="tag">步骤 #2</span> - <span>预期提示内容为:请输入验证码(区分大小写)</span> - </div> - <div class="case_step"> - <span class="tag">步骤 #3</span> - <span>获取登录提示内容</span> - </div> - <div class="checkpoint_pass"> - <span class="tag">检查点 PASS</span> - <span>校验提示内容是否跟预定结果一致</span> - </div> - <div> - <img class="screenshot" src="imgs/20250114175115432773.png" width="50%"> - </div> - </div> - </div> - </div> - <div class="case fail" id="case_00000004"> - <div class="folder_header"> - <span class="label caselabel">用例 FAIL</span> - <span class="casename">用户登录-004-登录账号不存在</span> - <span class="executetime">2025-01-14 17:51:15</span> - </div> - <div class="folder_body"> - <span class="case_class_path">cases\01登录模块\管理员登录.py::User_Login</span> - <div class="test_steps" id="test_steps 用户登录-004-登录账号不存在"> - <span class="label">测试步骤</span> - <div class="case_step"> - <span class="tag">步骤 #1</span> - <span>test_user1 用户登录测试</span> - </div> - <div class="info">输入登录账号: test_user1</div> - <div class="info">输入登录密码: ub@1234567</div> - <div class="info">输入验证码:csba</div> - <div class="info">点击登录按钮</div> - <div class="case_step"> - <span class="tag">步骤 #2</span> - <span>预期提示内容为:请检则用户名或密码是否正确!</span> - </div> - <div class="case_step"> - <span class="tag">步骤 #3</span> - <span>获取登录提示内容</span> - </div> - <div class="checkpoint_fail"> - <span class="tag">检查点 FAIL</span> - <span>校验提示内容是否跟预定结果一致</span> - </div> - <div class="info error-info"> -Traceback: - File "D:\GithubData\自动化\ubains-module-test\运维集控\项目测试\运维标准版\cases\01登录模块\管理员登录.py", line 39, in teststeps - CHECK_POINT('校验提示内容是否跟预定结果一致', get_text == info)</div> - </div> - </div> - </div> - <div class="case pass" id="case_00000005"> - <div class="folder_header"> - <span class="label caselabel">用例 PASS</span> - <span class="casename">用户登录-005-登录密码错误</span> - <span class="executetime">2025-01-14 17:51:18</span> - </div> - <div class="folder_body"> - <span class="case_class_path">cases\01登录模块\管理员登录.py::User_Login</span> - <div class="test_steps" id="test_steps 用户登录-005-登录密码错误"> - <span class="label">测试步骤</span> - <div class="case_step"> - <span class="tag">步骤 #1</span> - <span>admin@pgy 用户登录测试</span> - </div> - <div class="info">输入登录账号: admin@pgy</div> - <div class="info">输入登录密码: ub@1234567</div> - <div class="info">输入验证码:csba</div> - <div class="info">点击登录按钮</div> - <div class="case_step"> - <span class="tag">步骤 #2</span> - <span>预期提示内容为:输入的用户或密码不一致,</span> - </div> - <div class="case_step"> - <span class="tag">步骤 #3</span> - <span>获取登录提示内容</span> - </div> - <div class="checkpoint_pass"> - <span class="tag">检查点 PASS</span> - <span>校验提示内容是否跟预定结果一致</span> - </div> - <div> - <img class="screenshot" src="imgs/20250114175120369820.png" width="50%"> - </div> - </div> - </div> - </div> - <div class="case pass" id="case_00000006"> - <div class="folder_header"> - <span class="label caselabel">用例 PASS</span> - <span class="casename">用户登录-006-正常登录</span> - <span class="executetime">2025-01-14 17:51:20</span> - </div> - <div class="folder_body"> - <span class="case_class_path">cases\01登录模块\管理员登录.py::User_Login</span> - <div class="test_steps" id="test_steps 用户登录-006-正常登录"> - <span class="label">测试步骤</span> - <div class="case_step"> - <span class="tag">步骤 #1</span> - <span>admin@pgy 用户登录测试</span> - </div> - <div class="info">输入登录账号: admin@pgy</div> - <div class="info">输入登录密码: ub@123456</div> - <div class="info">输入验证码:csba</div> - <div class="info">点击登录按钮</div> - <div class="case_step"> - <span class="tag">步骤 #2</span> - <span>预期提示内容为:登录成功</span> - </div> - <div class="case_step"> - <span class="tag">步骤 #3</span> - <span>获取登录提示内容</span> - </div> - <div class="checkpoint_pass"> - <span class="tag">检查点 PASS</span> - <span>校验提示内容是否跟预定结果一致</span> - </div> - <div> - <img class="screenshot" src="imgs/20250114175123067561.png" width="50%"> - </div> - </div> - </div> - </div> - </div> - <div class="suite_dir" id="suite_dir cases\02用户管理\"> - <div> - <span class="label">进入目录</span> - <span>cases\02用户管理\</span> - </div> - <div class="suite_setup setup" id="suite_setup setup cases\02用户管理\"> - <div class="folder_header"> - <span class="label">套件初始化</span> - <span>cases\02用户管理\</span> - <span class="executetime">2025-01-14 17:51:23</span> - </div> - <div class="folder_body"></div> - </div> - </div> - <div class="suite_file" id="suite_file cases\02用户管理\01新增用户.py"> - <div> - <span class="label">进入文件</span> - <span>cases\02用户管理\01新增用户.py</span> - </div> - <div class="case pass" id="case_00000007"> - <div class="folder_header"> - <span class="label caselabel">用例 PASS</span> - <span class="casename">新增用户-001-登录名为空</span> - <span class="executetime">2025-01-14 17:51:23</span> - </div> - <div class="folder_body"> - <span class="case_class_path">cases\02用户管理\01新增用户.py::UserAdd</span> - <div class="test_steps" id="test_steps 新增用户-001-登录名为空"> - <span class="label">测试步骤</span> - <div class="case_step"> - <span class="tag">步骤 #1</span> - <span>点击新增按钮</span> - </div> - <div class="case_step"> - <span class="tag">步骤 #2</span> - <span>填写登录名: </span> - </div> - <div class="case_step"> - <span class="tag">步骤 #3</span> - <span>填写用户名称: test_user1</span> - </div> - <div class="case_step"> - <span class="tag">步骤 #4</span> - <span>填写新的密码: Ubains@123</span> - </div> - <div class="case_step"> - <span class="tag">步骤 #5</span> - <span>填写确认密码: Ubains@123</span> - </div> - <div class="case_step"> - <span class="tag">步骤 #6</span> - <span>选择权限: 普通用户</span> - </div> - <div class="case_step"> - <span class="tag">步骤 #7</span> - <span>填写用户工号: 13579</span> - </div> - <div class="case_step"> - <span class="tag">步骤 #8</span> - <span>填写手机号: 13169678901</span> - </div> - <div class="case_step"> - <span class="tag">步骤 #9</span> - <span>填写邮箱: test1@qq.com</span> - </div> - <div class="case_step"> - <span class="tag">步骤 #10</span> - <span>填写备注: test1</span> - </div> - <div class="case_step"> - <span class="tag">步骤 #11</span> - <span>点击“确认”按钮</span> - </div> - <div class="case_step"> - <span class="tag">步骤 #12</span> - <span>预期提示内容为:请输入登录名</span> - </div> - <div class="case_step"> - <span class="tag">步骤 #13</span> - <span>获取页面实际提示内容</span> - </div> - <div class="checkpoint_pass"> - <span class="tag">检查点 PASS</span> - <span>校验实际提示内容和预期提示内容是否一致</span> - </div> - <div> - <img class="screenshot" src="imgs/20250114175127528388.png" width="50%"> - </div> - </div> - </div> - </div> - <div class="case fail" id="case_00000008"> - <div class="folder_header"> - <span class="label caselabel">用例 FAIL</span> - <span class="casename">新增用户-002-用户名称为空</span> - <span class="executetime">2025-01-14 17:51:27</span> - </div> - <div class="folder_body"> - <span class="case_class_path">cases\02用户管理\01新增用户.py::UserAdd</span> - <div class="test_steps" id="test_steps 新增用户-002-用户名称为空"> - <span class="label">测试步骤</span> - <div class="case_step"> - <span class="tag">步骤 #1</span> - <span>点击新增按钮</span> - </div> - <div class="case_step"> - <span class="tag">步骤 #2</span> - <span>填写登录名: test_user1</span> - </div> - <div class="case_step"> - <span class="tag">步骤 #3</span> - <span>填写用户名称: </span> - </div> - <div class="case_step"> - <span class="tag">步骤 #4</span> - <span>填写新的密码: Ubains@123</span> - </div> - <div class="case_step"> - <span class="tag">步骤 #5</span> - <span>填写确认密码: Ubains@123</span> - </div> - <div class="case_step"> - <span class="tag">步骤 #6</span> - <span>选择权限: 普通用户</span> - </div> - <div class="case_step"> - <span class="tag">步骤 #7</span> - <span>填写用户工号: 13579</span> - </div> - <div class="case_step"> - <span class="tag">步骤 #8</span> - <span>填写手机号: 13169678901</span> - </div> - <div class="case_step"> - <span class="tag">步骤 #9</span> - <span>填写邮箱: test1@qq.com</span> - </div> - <div class="case_step"> - <span class="tag">步骤 #10</span> - <span>填写备注: test1</span> - </div> - <div class="case_step"> - <span class="tag">步骤 #11</span> - <span>点击“确认”按钮</span> - </div> - <div class="case_step"> - <span class="tag">步骤 #12</span> - <span>预期提示内容为:请输入用户名称</span> - </div> - <div class="case_step"> - <span class="tag">步骤 #13</span> - <span>获取页面实际提示内容</span> - </div> - <div class="checkpoint_fail"> - <span class="tag">检查点 FAIL</span> - <span>校验实际提示内容和预期提示内容是否一致</span> - </div> - <div class="info error-info"> -Traceback: - File "D:\GithubData\自动化\ubains-module-test\运维集控\项目测试\运维标准版\cases\02用户管理\01新增用户.py", line 116, in teststeps - CHECK_POINT('校验实际提示内容和预期提示内容是否一致', get_menu1 == info)</div> - </div> - </div> - </div> - <div class="case abort" id="case_00000009"> - <div class="folder_header"> - <span class="label caselabel">用例 ABORT</span> - <span class="casename">新增用户-003-密码为空</span> - <span class="executetime">2025-01-14 17:51:31</span> - </div> - <div class="folder_body"> - <span class="case_class_path">cases\02用户管理\01新增用户.py::UserAdd</span> - <div class="test_steps" id="test_steps 新增用户-003-密码为空"> - <span class="label">测试步骤</span> - <div class="case_step"> - <span class="tag">步骤 #1</span> - <span>点击新增按钮</span> - </div> - <div class="info error-info">Message: element click intercepted: Element <span data-v-2c75ef36="">...</span> is not clickable at point (1702, 129). Other element would receive the click: <div data-v-2c75ef36="" class="el-dialog__wrapper" style="z-index: 2001;">...</div> - (Session info: MicrosoftEdge=131.0.2903.146) -Stacktrace: - (No symbol) [0x00007FF6CD606B05] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD92F444+1437348] - sqlite3_dbdata_init [0x00007FF6CD9D2D76+643174] - (No symbol) [0x00007FF6CD532E8A] - (No symbol) [0x00007FF6CD530FEC] - (No symbol) [0x00007FF6CD52EC27] - (No symbol) [0x00007FF6CD52DF29] - (No symbol) [0x00007FF6CD523EB3] - (No symbol) [0x00007FF6CD54C19A] - (No symbol) [0x00007FF6CD523437] - (No symbol) [0x00007FF6CD5232FD] - (No symbol) [0x00007FF6CD54C480] - (No symbol) [0x00007FF6CD523437] - (No symbol) [0x00007FF6CD566BFF] - (No symbol) [0x00007FF6CD54BE03] - (No symbol) [0x00007FF6CD522984] - (No symbol) [0x00007FF6CD521E30] - (No symbol) [0x00007FF6CD522571] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DBAD4+1094964] - (No symbol) [0x00007FF6CD6432B8] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DAF13+1091955] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DAA79+1090777] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6E0C81+461569] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6DC9A4+444452] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6DCAE9+444777] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6D2166+401382] - BaseThreadInitThunk [0x00007FFFDD52259D+29] - RtlUserThreadStart [0x00007FFFDF26AF38+40] - -Traceback: - File "D:\GithubData\自动化\ubains-module-test\运维集控\项目测试\运维标准版\cases\02用户管理\01新增用户.py", line 26, in teststeps - user_add.click() - File "C:\Users\29194\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\webelement.py", line 94, in click - self._execute(Command.CLICK_ELEMENT) - File "C:\Users\29194\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\webelement.py", line 395, in _execute - return self._parent.execute(command, params) - File "C:\Users\29194\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 384, in execute - self.error_handler.check_response(response) - File "C:\Users\29194\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 232, in check_response - raise exception_class(message, screen, stacktrace) -selenium.common.exceptions.ElementClickInterceptedException: Message: element click intercepted: Element <span data-v-2c75ef36="">...</span> is not clickable at point (1702, 129). Other element would receive the click: <div data-v-2c75ef36="" class="el-dialog__wrapper" style="z-index: 2001;">...</div> - (Session info: MicrosoftEdge=131.0.2903.146) -Stacktrace: - (No symbol) [0x00007FF6CD606B05] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD92F444+1437348] - sqlite3_dbdata_init [0x00007FF6CD9D2D76+643174] - (No symbol) [0x00007FF6CD532E8A] - (No symbol) [0x00007FF6CD530FEC] - (No symbol) [0x00007FF6CD52EC27] - (No symbol) [0x00007FF6CD52DF29] - (No symbol) [0x00007FF6CD523EB3] - (No symbol) [0x00007FF6CD54C19A] - (No symbol) [0x00007FF6CD523437] - (No symbol) [0x00007FF6CD5232FD] - (No symbol) [0x00007FF6CD54C480] - (No symbol) [0x00007FF6CD523437] - (No symbol) [0x00007FF6CD566BFF] - (No symbol) [0x00007FF6CD54BE03] - (No symbol) [0x00007FF6CD522984] - (No symbol) [0x00007FF6CD521E30] - (No symbol) [0x00007FF6CD522571] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DBAD4+1094964] - (No symbol) [0x00007FF6CD6432B8] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DAF13+1091955] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DAA79+1090777] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6E0C81+461569] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6DC9A4+444452] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6DCAE9+444777] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6D2166+401382] - BaseThreadInitThunk [0x00007FFFDD52259D+29] - RtlUserThreadStart [0x00007FFFDF26AF38+40] - -</div> - </div> - </div> - </div> - <div class="case abort" id="case_00000010"> - <div class="folder_header"> - <span class="label caselabel">用例 ABORT</span> - <span class="casename">新增用户-004-确认密码为空</span> - <span class="executetime">2025-01-14 17:51:32</span> - </div> - <div class="folder_body"> - <span class="case_class_path">cases\02用户管理\01新增用户.py::UserAdd</span> - <div class="test_steps" id="test_steps 新增用户-004-确认密码为空"> - <span class="label">测试步骤</span> - <div class="case_step"> - <span class="tag">步骤 #1</span> - <span>点击新增按钮</span> - </div> - <div class="info error-info">Message: element click intercepted: Element <span data-v-2c75ef36="">...</span> is not clickable at point (1702, 129). Other element would receive the click: <div data-v-2c75ef36="" class="el-dialog__wrapper" style="z-index: 2001;">...</div> - (Session info: MicrosoftEdge=131.0.2903.146) -Stacktrace: - (No symbol) [0x00007FF6CD606B05] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD92F444+1437348] - sqlite3_dbdata_init [0x00007FF6CD9D2D76+643174] - (No symbol) [0x00007FF6CD532E8A] - (No symbol) [0x00007FF6CD530FEC] - (No symbol) [0x00007FF6CD52EC27] - (No symbol) [0x00007FF6CD52DF29] - (No symbol) [0x00007FF6CD523EB3] - (No symbol) [0x00007FF6CD54C19A] - (No symbol) [0x00007FF6CD523437] - (No symbol) [0x00007FF6CD5232FD] - (No symbol) [0x00007FF6CD54C480] - (No symbol) [0x00007FF6CD523437] - (No symbol) [0x00007FF6CD566BFF] - (No symbol) [0x00007FF6CD54BE03] - (No symbol) [0x00007FF6CD522984] - (No symbol) [0x00007FF6CD521E30] - (No symbol) [0x00007FF6CD522571] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DBAD4+1094964] - (No symbol) [0x00007FF6CD6432B8] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DAF13+1091955] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DAA79+1090777] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6E0C81+461569] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6DC9A4+444452] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6DCAE9+444777] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6D2166+401382] - BaseThreadInitThunk [0x00007FFFDD52259D+29] - RtlUserThreadStart [0x00007FFFDF26AF38+40] - -Traceback: - File "D:\GithubData\自动化\ubains-module-test\运维集控\项目测试\运维标准版\cases\02用户管理\01新增用户.py", line 26, in teststeps - user_add.click() - File "C:\Users\29194\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\webelement.py", line 94, in click - self._execute(Command.CLICK_ELEMENT) - File "C:\Users\29194\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\webelement.py", line 395, in _execute - return self._parent.execute(command, params) - File "C:\Users\29194\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 384, in execute - self.error_handler.check_response(response) - File "C:\Users\29194\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 232, in check_response - raise exception_class(message, screen, stacktrace) -selenium.common.exceptions.ElementClickInterceptedException: Message: element click intercepted: Element <span data-v-2c75ef36="">...</span> is not clickable at point (1702, 129). Other element would receive the click: <div data-v-2c75ef36="" class="el-dialog__wrapper" style="z-index: 2001;">...</div> - (Session info: MicrosoftEdge=131.0.2903.146) -Stacktrace: - (No symbol) [0x00007FF6CD606B05] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD92F444+1437348] - sqlite3_dbdata_init [0x00007FF6CD9D2D76+643174] - (No symbol) [0x00007FF6CD532E8A] - (No symbol) [0x00007FF6CD530FEC] - (No symbol) [0x00007FF6CD52EC27] - (No symbol) [0x00007FF6CD52DF29] - (No symbol) [0x00007FF6CD523EB3] - (No symbol) [0x00007FF6CD54C19A] - (No symbol) [0x00007FF6CD523437] - (No symbol) [0x00007FF6CD5232FD] - (No symbol) [0x00007FF6CD54C480] - (No symbol) [0x00007FF6CD523437] - (No symbol) [0x00007FF6CD566BFF] - (No symbol) [0x00007FF6CD54BE03] - (No symbol) [0x00007FF6CD522984] - (No symbol) [0x00007FF6CD521E30] - (No symbol) [0x00007FF6CD522571] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DBAD4+1094964] - (No symbol) [0x00007FF6CD6432B8] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DAF13+1091955] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DAA79+1090777] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6E0C81+461569] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6DC9A4+444452] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6DCAE9+444777] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6D2166+401382] - BaseThreadInitThunk [0x00007FFFDD52259D+29] - RtlUserThreadStart [0x00007FFFDF26AF38+40] - -</div> - </div> - </div> - </div> - <div class="case abort" id="case_00000011"> - <div class="folder_header"> - <span class="label caselabel">用例 ABORT</span> - <span class="casename">新增用户-005-密码和账号相同</span> - <span class="executetime">2025-01-14 17:51:33</span> - </div> - <div class="folder_body"> - <span class="case_class_path">cases\02用户管理\01新增用户.py::UserAdd</span> - <div class="test_steps" id="test_steps 新增用户-005-密码和账号相同"> - <span class="label">测试步骤</span> - <div class="case_step"> - <span class="tag">步骤 #1</span> - <span>点击新增按钮</span> - </div> - <div class="info error-info">Message: element click intercepted: Element <span data-v-2c75ef36="">...</span> is not clickable at point (1702, 129). Other element would receive the click: <div data-v-2c75ef36="" class="el-dialog__wrapper" style="z-index: 2001;">...</div> - (Session info: MicrosoftEdge=131.0.2903.146) -Stacktrace: - (No symbol) [0x00007FF6CD606B05] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD92F444+1437348] - sqlite3_dbdata_init [0x00007FF6CD9D2D76+643174] - (No symbol) [0x00007FF6CD532E8A] - (No symbol) [0x00007FF6CD530FEC] - (No symbol) [0x00007FF6CD52EC27] - (No symbol) [0x00007FF6CD52DF29] - (No symbol) [0x00007FF6CD523EB3] - (No symbol) [0x00007FF6CD54C19A] - (No symbol) [0x00007FF6CD523437] - (No symbol) [0x00007FF6CD5232FD] - (No symbol) [0x00007FF6CD54C480] - (No symbol) [0x00007FF6CD523437] - (No symbol) [0x00007FF6CD566BFF] - (No symbol) [0x00007FF6CD54BE03] - (No symbol) [0x00007FF6CD522984] - (No symbol) [0x00007FF6CD521E30] - (No symbol) [0x00007FF6CD522571] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DBAD4+1094964] - (No symbol) [0x00007FF6CD6432B8] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DAF13+1091955] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DAA79+1090777] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6E0C81+461569] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6DC9A4+444452] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6DCAE9+444777] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6D2166+401382] - BaseThreadInitThunk [0x00007FFFDD52259D+29] - RtlUserThreadStart [0x00007FFFDF26AF38+40] - -Traceback: - File "D:\GithubData\自动化\ubains-module-test\运维集控\项目测试\运维标准版\cases\02用户管理\01新增用户.py", line 26, in teststeps - user_add.click() - File "C:\Users\29194\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\webelement.py", line 94, in click - self._execute(Command.CLICK_ELEMENT) - File "C:\Users\29194\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\webelement.py", line 395, in _execute - return self._parent.execute(command, params) - File "C:\Users\29194\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 384, in execute - self.error_handler.check_response(response) - File "C:\Users\29194\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 232, in check_response - raise exception_class(message, screen, stacktrace) -selenium.common.exceptions.ElementClickInterceptedException: Message: element click intercepted: Element <span data-v-2c75ef36="">...</span> is not clickable at point (1702, 129). Other element would receive the click: <div data-v-2c75ef36="" class="el-dialog__wrapper" style="z-index: 2001;">...</div> - (Session info: MicrosoftEdge=131.0.2903.146) -Stacktrace: - (No symbol) [0x00007FF6CD606B05] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD92F444+1437348] - sqlite3_dbdata_init [0x00007FF6CD9D2D76+643174] - (No symbol) [0x00007FF6CD532E8A] - (No symbol) [0x00007FF6CD530FEC] - (No symbol) [0x00007FF6CD52EC27] - (No symbol) [0x00007FF6CD52DF29] - (No symbol) [0x00007FF6CD523EB3] - (No symbol) [0x00007FF6CD54C19A] - (No symbol) [0x00007FF6CD523437] - (No symbol) [0x00007FF6CD5232FD] - (No symbol) [0x00007FF6CD54C480] - (No symbol) [0x00007FF6CD523437] - (No symbol) [0x00007FF6CD566BFF] - (No symbol) [0x00007FF6CD54BE03] - (No symbol) [0x00007FF6CD522984] - (No symbol) [0x00007FF6CD521E30] - (No symbol) [0x00007FF6CD522571] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DBAD4+1094964] - (No symbol) [0x00007FF6CD6432B8] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DAF13+1091955] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DAA79+1090777] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6E0C81+461569] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6DC9A4+444452] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6DCAE9+444777] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6D2166+401382] - BaseThreadInitThunk [0x00007FFFDD52259D+29] - RtlUserThreadStart [0x00007FFFDF26AF38+40] - -</div> - </div> - </div> - </div> - <div class="case abort" id="case_00000012"> - <div class="folder_header"> - <span class="label caselabel">用例 ABORT</span> - <span class="casename">新增用户-006-正常创建1</span> - <span class="executetime">2025-01-14 17:51:34</span> - </div> - <div class="folder_body"> - <span class="case_class_path">cases\02用户管理\01新增用户.py::UserAdd</span> - <div class="test_steps" id="test_steps 新增用户-006-正常创建1"> - <span class="label">测试步骤</span> - <div class="case_step"> - <span class="tag">步骤 #1</span> - <span>点击新增按钮</span> - </div> - <div class="info error-info">Message: element click intercepted: Element <span data-v-2c75ef36="">...</span> is not clickable at point (1702, 129). Other element would receive the click: <div data-v-2c75ef36="" class="el-dialog__wrapper" style="z-index: 2001;">...</div> - (Session info: MicrosoftEdge=131.0.2903.146) -Stacktrace: - (No symbol) [0x00007FF6CD606B05] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD92F444+1437348] - sqlite3_dbdata_init [0x00007FF6CD9D2D76+643174] - (No symbol) [0x00007FF6CD532E8A] - (No symbol) [0x00007FF6CD530FEC] - (No symbol) [0x00007FF6CD52EC27] - (No symbol) [0x00007FF6CD52DF29] - (No symbol) [0x00007FF6CD523EB3] - (No symbol) [0x00007FF6CD54C19A] - (No symbol) [0x00007FF6CD523437] - (No symbol) [0x00007FF6CD5232FD] - (No symbol) [0x00007FF6CD54C480] - (No symbol) [0x00007FF6CD523437] - (No symbol) [0x00007FF6CD566BFF] - (No symbol) [0x00007FF6CD54BE03] - (No symbol) [0x00007FF6CD522984] - (No symbol) [0x00007FF6CD521E30] - (No symbol) [0x00007FF6CD522571] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DBAD4+1094964] - (No symbol) [0x00007FF6CD6432B8] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DAF13+1091955] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DAA79+1090777] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6E0C81+461569] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6DC9A4+444452] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6DCAE9+444777] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6D2166+401382] - BaseThreadInitThunk [0x00007FFFDD52259D+29] - RtlUserThreadStart [0x00007FFFDF26AF38+40] - -Traceback: - File "D:\GithubData\自动化\ubains-module-test\运维集控\项目测试\运维标准版\cases\02用户管理\01新增用户.py", line 26, in teststeps - user_add.click() - File "C:\Users\29194\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\webelement.py", line 94, in click - self._execute(Command.CLICK_ELEMENT) - File "C:\Users\29194\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\webelement.py", line 395, in _execute - return self._parent.execute(command, params) - File "C:\Users\29194\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 384, in execute - self.error_handler.check_response(response) - File "C:\Users\29194\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 232, in check_response - raise exception_class(message, screen, stacktrace) -selenium.common.exceptions.ElementClickInterceptedException: Message: element click intercepted: Element <span data-v-2c75ef36="">...</span> is not clickable at point (1702, 129). Other element would receive the click: <div data-v-2c75ef36="" class="el-dialog__wrapper" style="z-index: 2001;">...</div> - (Session info: MicrosoftEdge=131.0.2903.146) -Stacktrace: - (No symbol) [0x00007FF6CD606B05] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD92F444+1437348] - sqlite3_dbdata_init [0x00007FF6CD9D2D76+643174] - (No symbol) [0x00007FF6CD532E8A] - (No symbol) [0x00007FF6CD530FEC] - (No symbol) [0x00007FF6CD52EC27] - (No symbol) [0x00007FF6CD52DF29] - (No symbol) [0x00007FF6CD523EB3] - (No symbol) [0x00007FF6CD54C19A] - (No symbol) [0x00007FF6CD523437] - (No symbol) [0x00007FF6CD5232FD] - (No symbol) [0x00007FF6CD54C480] - (No symbol) [0x00007FF6CD523437] - (No symbol) [0x00007FF6CD566BFF] - (No symbol) [0x00007FF6CD54BE03] - (No symbol) [0x00007FF6CD522984] - (No symbol) [0x00007FF6CD521E30] - (No symbol) [0x00007FF6CD522571] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DBAD4+1094964] - (No symbol) [0x00007FF6CD6432B8] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DAF13+1091955] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DAA79+1090777] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6E0C81+461569] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6DC9A4+444452] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6DCAE9+444777] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6D2166+401382] - BaseThreadInitThunk [0x00007FFFDD52259D+29] - RtlUserThreadStart [0x00007FFFDF26AF38+40] - -</div> - </div> - </div> - </div> - <div class="case abort" id="case_00000013"> - <div class="folder_header"> - <span class="label caselabel">用例 ABORT</span> - <span class="casename">新增用户-007-登录名重复</span> - <span class="executetime">2025-01-14 17:51:35</span> - </div> - <div class="folder_body"> - <span class="case_class_path">cases\02用户管理\01新增用户.py::UserAdd</span> - <div class="test_steps" id="test_steps 新增用户-007-登录名重复"> - <span class="label">测试步骤</span> - <div class="case_step"> - <span class="tag">步骤 #1</span> - <span>点击新增按钮</span> - </div> - <div class="info error-info">Message: element click intercepted: Element <span data-v-2c75ef36="">...</span> is not clickable at point (1702, 129). Other element would receive the click: <div data-v-2c75ef36="" class="el-dialog__wrapper" style="z-index: 2001;">...</div> - (Session info: MicrosoftEdge=131.0.2903.146) -Stacktrace: - (No symbol) [0x00007FF6CD606B05] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD92F444+1437348] - sqlite3_dbdata_init [0x00007FF6CD9D2D76+643174] - (No symbol) [0x00007FF6CD532E8A] - (No symbol) [0x00007FF6CD530FEC] - (No symbol) [0x00007FF6CD52EC27] - (No symbol) [0x00007FF6CD52DF29] - (No symbol) [0x00007FF6CD523EB3] - (No symbol) [0x00007FF6CD54C19A] - (No symbol) [0x00007FF6CD523437] - (No symbol) [0x00007FF6CD5232FD] - (No symbol) [0x00007FF6CD54C480] - (No symbol) [0x00007FF6CD523437] - (No symbol) [0x00007FF6CD566BFF] - (No symbol) [0x00007FF6CD54BE03] - (No symbol) [0x00007FF6CD522984] - (No symbol) [0x00007FF6CD521E30] - (No symbol) [0x00007FF6CD522571] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DBAD4+1094964] - (No symbol) [0x00007FF6CD6432B8] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DAF13+1091955] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DAA79+1090777] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6E0C81+461569] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6DC9A4+444452] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6DCAE9+444777] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6D2166+401382] - BaseThreadInitThunk [0x00007FFFDD52259D+29] - RtlUserThreadStart [0x00007FFFDF26AF38+40] - -Traceback: - File "D:\GithubData\自动化\ubains-module-test\运维集控\项目测试\运维标准版\cases\02用户管理\01新增用户.py", line 26, in teststeps - user_add.click() - File "C:\Users\29194\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\webelement.py", line 94, in click - self._execute(Command.CLICK_ELEMENT) - File "C:\Users\29194\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\webelement.py", line 395, in _execute - return self._parent.execute(command, params) - File "C:\Users\29194\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 384, in execute - self.error_handler.check_response(response) - File "C:\Users\29194\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 232, in check_response - raise exception_class(message, screen, stacktrace) -selenium.common.exceptions.ElementClickInterceptedException: Message: element click intercepted: Element <span data-v-2c75ef36="">...</span> is not clickable at point (1702, 129). Other element would receive the click: <div data-v-2c75ef36="" class="el-dialog__wrapper" style="z-index: 2001;">...</div> - (Session info: MicrosoftEdge=131.0.2903.146) -Stacktrace: - (No symbol) [0x00007FF6CD606B05] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD92F444+1437348] - sqlite3_dbdata_init [0x00007FF6CD9D2D76+643174] - (No symbol) [0x00007FF6CD532E8A] - (No symbol) [0x00007FF6CD530FEC] - (No symbol) [0x00007FF6CD52EC27] - (No symbol) [0x00007FF6CD52DF29] - (No symbol) [0x00007FF6CD523EB3] - (No symbol) [0x00007FF6CD54C19A] - (No symbol) [0x00007FF6CD523437] - (No symbol) [0x00007FF6CD5232FD] - (No symbol) [0x00007FF6CD54C480] - (No symbol) [0x00007FF6CD523437] - (No symbol) [0x00007FF6CD566BFF] - (No symbol) [0x00007FF6CD54BE03] - (No symbol) [0x00007FF6CD522984] - (No symbol) [0x00007FF6CD521E30] - (No symbol) [0x00007FF6CD522571] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DBAD4+1094964] - (No symbol) [0x00007FF6CD6432B8] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DAF13+1091955] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DAA79+1090777] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6E0C81+461569] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6DC9A4+444452] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6DCAE9+444777] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6D2166+401382] - BaseThreadInitThunk [0x00007FFFDD52259D+29] - RtlUserThreadStart [0x00007FFFDF26AF38+40] - -</div> - </div> - </div> - </div> - <div class="case abort" id="case_00000014"> - <div class="folder_header"> - <span class="label caselabel">用例 ABORT</span> - <span class="casename">新增用户-008-正常创建用户2</span> - <span class="executetime">2025-01-14 17:51:36</span> - </div> - <div class="folder_body"> - <span class="case_class_path">cases\02用户管理\01新增用户.py::UserAdd</span> - <div class="test_steps" id="test_steps 新增用户-008-正常创建用户2"> - <span class="label">测试步骤</span> - <div class="case_step"> - <span class="tag">步骤 #1</span> - <span>点击新增按钮</span> - </div> - <div class="info error-info">Message: element click intercepted: Element <span data-v-2c75ef36="">...</span> is not clickable at point (1702, 129). Other element would receive the click: <div data-v-2c75ef36="" class="el-dialog__wrapper" style="z-index: 2001;">...</div> - (Session info: MicrosoftEdge=131.0.2903.146) -Stacktrace: - (No symbol) [0x00007FF6CD606B05] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD92F444+1437348] - sqlite3_dbdata_init [0x00007FF6CD9D2D76+643174] - (No symbol) [0x00007FF6CD532E8A] - (No symbol) [0x00007FF6CD530FEC] - (No symbol) [0x00007FF6CD52EC27] - (No symbol) [0x00007FF6CD52DF29] - (No symbol) [0x00007FF6CD523EB3] - (No symbol) [0x00007FF6CD54C19A] - (No symbol) [0x00007FF6CD523437] - (No symbol) [0x00007FF6CD5232FD] - (No symbol) [0x00007FF6CD54C480] - (No symbol) [0x00007FF6CD523437] - (No symbol) [0x00007FF6CD566BFF] - (No symbol) [0x00007FF6CD54BE03] - (No symbol) [0x00007FF6CD522984] - (No symbol) [0x00007FF6CD521E30] - (No symbol) [0x00007FF6CD522571] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DBAD4+1094964] - (No symbol) [0x00007FF6CD6432B8] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DAF13+1091955] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DAA79+1090777] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6E0C81+461569] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6DC9A4+444452] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6DCAE9+444777] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6D2166+401382] - BaseThreadInitThunk [0x00007FFFDD52259D+29] - RtlUserThreadStart [0x00007FFFDF26AF38+40] - -Traceback: - File "D:\GithubData\自动化\ubains-module-test\运维集控\项目测试\运维标准版\cases\02用户管理\01新增用户.py", line 26, in teststeps - user_add.click() - File "C:\Users\29194\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\webelement.py", line 94, in click - self._execute(Command.CLICK_ELEMENT) - File "C:\Users\29194\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\webelement.py", line 395, in _execute - return self._parent.execute(command, params) - File "C:\Users\29194\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 384, in execute - self.error_handler.check_response(response) - File "C:\Users\29194\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 232, in check_response - raise exception_class(message, screen, stacktrace) -selenium.common.exceptions.ElementClickInterceptedException: Message: element click intercepted: Element <span data-v-2c75ef36="">...</span> is not clickable at point (1702, 129). Other element would receive the click: <div data-v-2c75ef36="" class="el-dialog__wrapper" style="z-index: 2001;">...</div> - (Session info: MicrosoftEdge=131.0.2903.146) -Stacktrace: - (No symbol) [0x00007FF6CD606B05] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD92F444+1437348] - sqlite3_dbdata_init [0x00007FF6CD9D2D76+643174] - (No symbol) [0x00007FF6CD532E8A] - (No symbol) [0x00007FF6CD530FEC] - (No symbol) [0x00007FF6CD52EC27] - (No symbol) [0x00007FF6CD52DF29] - (No symbol) [0x00007FF6CD523EB3] - (No symbol) [0x00007FF6CD54C19A] - (No symbol) [0x00007FF6CD523437] - (No symbol) [0x00007FF6CD5232FD] - (No symbol) [0x00007FF6CD54C480] - (No symbol) [0x00007FF6CD523437] - (No symbol) [0x00007FF6CD566BFF] - (No symbol) [0x00007FF6CD54BE03] - (No symbol) [0x00007FF6CD522984] - (No symbol) [0x00007FF6CD521E30] - (No symbol) [0x00007FF6CD522571] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DBAD4+1094964] - (No symbol) [0x00007FF6CD6432B8] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DAF13+1091955] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DAA79+1090777] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6E0C81+461569] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6DC9A4+444452] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6DCAE9+444777] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6D2166+401382] - BaseThreadInitThunk [0x00007FFFDD52259D+29] - RtlUserThreadStart [0x00007FFFDF26AF38+40] - -</div> - </div> - </div> - </div> - <div class="case abort" id="case_00000015"> - <div class="folder_header"> - <span class="label caselabel">用例 ABORT</span> - <span class="casename">新增用户-009-正常创建用户3</span> - <span class="executetime">2025-01-14 17:51:38</span> - </div> - <div class="folder_body"> - <span class="case_class_path">cases\02用户管理\01新增用户.py::UserAdd</span> - <div class="test_steps" id="test_steps 新增用户-009-正常创建用户3"> - <span class="label">测试步骤</span> - <div class="case_step"> - <span class="tag">步骤 #1</span> - <span>点击新增按钮</span> - </div> - <div class="info error-info">Message: element click intercepted: Element <span data-v-2c75ef36="">...</span> is not clickable at point (1702, 129). Other element would receive the click: <div data-v-2c75ef36="" class="el-dialog__wrapper" style="z-index: 2001;">...</div> - (Session info: MicrosoftEdge=131.0.2903.146) -Stacktrace: - (No symbol) [0x00007FF6CD606B05] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD92F444+1437348] - sqlite3_dbdata_init [0x00007FF6CD9D2D76+643174] - (No symbol) [0x00007FF6CD532E8A] - (No symbol) [0x00007FF6CD530FEC] - (No symbol) [0x00007FF6CD52EC27] - (No symbol) [0x00007FF6CD52DF29] - (No symbol) [0x00007FF6CD523EB3] - (No symbol) [0x00007FF6CD54C19A] - (No symbol) [0x00007FF6CD523437] - (No symbol) [0x00007FF6CD5232FD] - (No symbol) [0x00007FF6CD54C480] - (No symbol) [0x00007FF6CD523437] - (No symbol) [0x00007FF6CD566BFF] - (No symbol) [0x00007FF6CD54BE03] - (No symbol) [0x00007FF6CD522984] - (No symbol) [0x00007FF6CD521E30] - (No symbol) [0x00007FF6CD522571] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DBAD4+1094964] - (No symbol) [0x00007FF6CD6432B8] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DAF13+1091955] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DAA79+1090777] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6E0C81+461569] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6DC9A4+444452] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6DCAE9+444777] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6D2166+401382] - BaseThreadInitThunk [0x00007FFFDD52259D+29] - RtlUserThreadStart [0x00007FFFDF26AF38+40] - -Traceback: - File "D:\GithubData\自动化\ubains-module-test\运维集控\项目测试\运维标准版\cases\02用户管理\01新增用户.py", line 26, in teststeps - user_add.click() - File "C:\Users\29194\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\webelement.py", line 94, in click - self._execute(Command.CLICK_ELEMENT) - File "C:\Users\29194\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\webelement.py", line 395, in _execute - return self._parent.execute(command, params) - File "C:\Users\29194\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 384, in execute - self.error_handler.check_response(response) - File "C:\Users\29194\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 232, in check_response - raise exception_class(message, screen, stacktrace) -selenium.common.exceptions.ElementClickInterceptedException: Message: element click intercepted: Element <span data-v-2c75ef36="">...</span> is not clickable at point (1702, 129). Other element would receive the click: <div data-v-2c75ef36="" class="el-dialog__wrapper" style="z-index: 2001;">...</div> - (Session info: MicrosoftEdge=131.0.2903.146) -Stacktrace: - (No symbol) [0x00007FF6CD606B05] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD92F444+1437348] - sqlite3_dbdata_init [0x00007FF6CD9D2D76+643174] - (No symbol) [0x00007FF6CD532E8A] - (No symbol) [0x00007FF6CD530FEC] - (No symbol) [0x00007FF6CD52EC27] - (No symbol) [0x00007FF6CD52DF29] - (No symbol) [0x00007FF6CD523EB3] - (No symbol) [0x00007FF6CD54C19A] - (No symbol) [0x00007FF6CD523437] - (No symbol) [0x00007FF6CD5232FD] - (No symbol) [0x00007FF6CD54C480] - (No symbol) [0x00007FF6CD523437] - (No symbol) [0x00007FF6CD566BFF] - (No symbol) [0x00007FF6CD54BE03] - (No symbol) [0x00007FF6CD522984] - (No symbol) [0x00007FF6CD521E30] - (No symbol) [0x00007FF6CD522571] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DBAD4+1094964] - (No symbol) [0x00007FF6CD6432B8] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DAF13+1091955] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DAA79+1090777] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6E0C81+461569] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6DC9A4+444452] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6DCAE9+444777] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6D2166+401382] - BaseThreadInitThunk [0x00007FFFDD52259D+29] - RtlUserThreadStart [0x00007FFFDF26AF38+40] - -</div> - </div> - </div> - </div> - </div> - <div class="suite_file" id="suite_file cases\02用户管理\02查询用户.py"> - <div> - <span class="label">进入文件</span> - <span>cases\02用户管理\02查询用户.py</span> - </div> - <div class="case abort" id="case_00000016"> - <div class="folder_header"> - <span class="label caselabel">用例 ABORT</span> - <span class="casename">user_query</span> - <span class="executetime">2025-01-14 17:51:39</span> - </div> - <div class="folder_body"> - <span class="case_class_path">cases\02用户管理\02查询用户.py::Userquery</span> - <div class="test_steps" id="test_steps user_query"> - <span class="label">测试步骤</span> - <div class="case_step"> - <span class="tag">步骤 #1</span> - <span>点击搜索框</span> - </div> - <div class="info error-info">Message: element click intercepted: Element <input type="text" autocomplete="off" placeholder="请输入用户名称" class="el-input__inner"> is not clickable at point (287, 129). Other element would receive the click: <div data-v-2c75ef36="" class="el-dialog__wrapper" style="z-index: 2001;">...</div> - (Session info: MicrosoftEdge=131.0.2903.146) -Stacktrace: - (No symbol) [0x00007FF6CD606B05] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD92F444+1437348] - sqlite3_dbdata_init [0x00007FF6CD9D2D76+643174] - (No symbol) [0x00007FF6CD532E8A] - (No symbol) [0x00007FF6CD530FEC] - (No symbol) [0x00007FF6CD52EC27] - (No symbol) [0x00007FF6CD52DF29] - (No symbol) [0x00007FF6CD523EB3] - (No symbol) [0x00007FF6CD54C19A] - (No symbol) [0x00007FF6CD523437] - (No symbol) [0x00007FF6CD5232FD] - (No symbol) [0x00007FF6CD54C480] - (No symbol) [0x00007FF6CD523437] - (No symbol) [0x00007FF6CD566BFF] - (No symbol) [0x00007FF6CD54BE03] - (No symbol) [0x00007FF6CD522984] - (No symbol) [0x00007FF6CD521E30] - (No symbol) [0x00007FF6CD522571] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DBAD4+1094964] - (No symbol) [0x00007FF6CD6432B8] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DAF13+1091955] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DAA79+1090777] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6E0C81+461569] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6DC9A4+444452] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6DCAE9+444777] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6D2166+401382] - BaseThreadInitThunk [0x00007FFFDD52259D+29] - RtlUserThreadStart [0x00007FFFDF26AF38+40] - -Traceback: - File "D:\GithubData\自动化\ubains-module-test\运维集控\项目测试\运维标准版\cases\02用户管理\02查询用户.py", line 16, in teststeps - user_query.click() - File "C:\Users\29194\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\webelement.py", line 94, in click - self._execute(Command.CLICK_ELEMENT) - File "C:\Users\29194\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\webelement.py", line 395, in _execute - return self._parent.execute(command, params) - File "C:\Users\29194\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 384, in execute - self.error_handler.check_response(response) - File "C:\Users\29194\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 232, in check_response - raise exception_class(message, screen, stacktrace) -selenium.common.exceptions.ElementClickInterceptedException: Message: element click intercepted: Element <input type="text" autocomplete="off" placeholder="请输入用户名称" class="el-input__inner"> is not clickable at point (287, 129). Other element would receive the click: <div data-v-2c75ef36="" class="el-dialog__wrapper" style="z-index: 2001;">...</div> - (Session info: MicrosoftEdge=131.0.2903.146) -Stacktrace: - (No symbol) [0x00007FF6CD606B05] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD92F444+1437348] - sqlite3_dbdata_init [0x00007FF6CD9D2D76+643174] - (No symbol) [0x00007FF6CD532E8A] - (No symbol) [0x00007FF6CD530FEC] - (No symbol) [0x00007FF6CD52EC27] - (No symbol) [0x00007FF6CD52DF29] - (No symbol) [0x00007FF6CD523EB3] - (No symbol) [0x00007FF6CD54C19A] - (No symbol) [0x00007FF6CD523437] - (No symbol) [0x00007FF6CD5232FD] - (No symbol) [0x00007FF6CD54C480] - (No symbol) [0x00007FF6CD523437] - (No symbol) [0x00007FF6CD566BFF] - (No symbol) [0x00007FF6CD54BE03] - (No symbol) [0x00007FF6CD522984] - (No symbol) [0x00007FF6CD521E30] - (No symbol) [0x00007FF6CD522571] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DBAD4+1094964] - (No symbol) [0x00007FF6CD6432B8] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DAF13+1091955] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DAA79+1090777] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6E0C81+461569] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6DC9A4+444452] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6DCAE9+444777] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6D2166+401382] - BaseThreadInitThunk [0x00007FFFDD52259D+29] - RtlUserThreadStart [0x00007FFFDF26AF38+40] - -</div> - </div> - </div> - </div> - </div> - <div class="suite_file" id="suite_file cases\02用户管理\03编辑用户.py"> - <div> - <span class="label">进入文件</span> - <span>cases\02用户管理\03编辑用户.py</span> - </div> - <div class="case abort" id="case_00000017"> - <div class="folder_header"> - <span class="label caselabel">用例 ABORT</span> - <span class="casename">user_modify_001</span> - <span class="executetime">2025-01-14 17:51:40</span> - </div> - <div class="folder_body"> - <span class="case_class_path">cases\02用户管理\03编辑用户.py::UserModify001</span> - <div class="test_steps" id="test_steps user_modify_001"> - <span class="label">测试步骤</span> - <div class="case_step"> - <span class="tag">步骤 #1</span> - <span>点击搜索框</span> - </div> - <div class="case_step"> - <span class="tag">步骤 #2</span> - <span>勾选用户</span> - </div> - <div class="info error-info">Message: element click intercepted: Element <span class="el-checkbox__inner"></span> is not clickable at point (212, 189). Other element would receive the click: <div data-v-2c75ef36="" class="el-dialog__wrapper" style="z-index: 2001;">...</div> - (Session info: MicrosoftEdge=131.0.2903.146) -Stacktrace: - (No symbol) [0x00007FF6CD606B05] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD92F444+1437348] - sqlite3_dbdata_init [0x00007FF6CD9D2D76+643174] - (No symbol) [0x00007FF6CD532E8A] - (No symbol) [0x00007FF6CD530FEC] - (No symbol) [0x00007FF6CD52EC27] - (No symbol) [0x00007FF6CD52DF29] - (No symbol) [0x00007FF6CD523EB3] - (No symbol) [0x00007FF6CD54C19A] - (No symbol) [0x00007FF6CD523437] - (No symbol) [0x00007FF6CD5232FD] - (No symbol) [0x00007FF6CD54C480] - (No symbol) [0x00007FF6CD523437] - (No symbol) [0x00007FF6CD566BFF] - (No symbol) [0x00007FF6CD54BE03] - (No symbol) [0x00007FF6CD522984] - (No symbol) [0x00007FF6CD521E30] - (No symbol) [0x00007FF6CD522571] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DBAD4+1094964] - (No symbol) [0x00007FF6CD6432B8] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DAF13+1091955] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DAA79+1090777] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6E0C81+461569] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6DC9A4+444452] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6DCAE9+444777] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6D2166+401382] - BaseThreadInitThunk [0x00007FFFDD52259D+29] - RtlUserThreadStart [0x00007FFFDF26AF38+40] - -Traceback: - File "D:\GithubData\自动化\ubains-module-test\运维集控\项目测试\运维标准版\cases\02用户管理\03编辑用户.py", line 23, in teststeps - select_click.click() - File "C:\Users\29194\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\webelement.py", line 94, in click - self._execute(Command.CLICK_ELEMENT) - File "C:\Users\29194\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\webelement.py", line 395, in _execute - return self._parent.execute(command, params) - File "C:\Users\29194\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 384, in execute - self.error_handler.check_response(response) - File "C:\Users\29194\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 232, in check_response - raise exception_class(message, screen, stacktrace) -selenium.common.exceptions.ElementClickInterceptedException: Message: element click intercepted: Element <span class="el-checkbox__inner"></span> is not clickable at point (212, 189). Other element would receive the click: <div data-v-2c75ef36="" class="el-dialog__wrapper" style="z-index: 2001;">...</div> - (Session info: MicrosoftEdge=131.0.2903.146) -Stacktrace: - (No symbol) [0x00007FF6CD606B05] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD92F444+1437348] - sqlite3_dbdata_init [0x00007FF6CD9D2D76+643174] - (No symbol) [0x00007FF6CD532E8A] - (No symbol) [0x00007FF6CD530FEC] - (No symbol) [0x00007FF6CD52EC27] - (No symbol) [0x00007FF6CD52DF29] - (No symbol) [0x00007FF6CD523EB3] - (No symbol) [0x00007FF6CD54C19A] - (No symbol) [0x00007FF6CD523437] - (No symbol) [0x00007FF6CD5232FD] - (No symbol) [0x00007FF6CD54C480] - (No symbol) [0x00007FF6CD523437] - (No symbol) [0x00007FF6CD566BFF] - (No symbol) [0x00007FF6CD54BE03] - (No symbol) [0x00007FF6CD522984] - (No symbol) [0x00007FF6CD521E30] - (No symbol) [0x00007FF6CD522571] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DBAD4+1094964] - (No symbol) [0x00007FF6CD6432B8] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DAF13+1091955] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DAA79+1090777] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6E0C81+461569] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6DC9A4+444452] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6DCAE9+444777] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6D2166+401382] - BaseThreadInitThunk [0x00007FFFDD52259D+29] - RtlUserThreadStart [0x00007FFFDF26AF38+40] - -</div> - </div> - </div> - </div> - </div> - <div class="suite_file" id="suite_file cases\02用户管理\04删除用户.py"> - <div> - <span class="label">进入文件</span> - <span>cases\02用户管理\04删除用户.py</span> - </div> - <div class="case abort" id="case_00000018"> - <div class="folder_header"> - <span class="label caselabel">用例 ABORT</span> - <span class="casename">user_delete_001</span> - <span class="executetime">2025-01-14 17:51:41</span> - </div> - <div class="folder_body"> - <span class="case_class_path">cases\02用户管理\04删除用户.py::Userdelete001</span> - <div class="test_steps" id="test_steps user_delete_001"> - <span class="label">测试步骤</span> - <div class="case_step"> - <span class="tag">步骤 #1</span> - <span>点击搜索框</span> - </div> - <div class="case_step"> - <span class="tag">步骤 #2</span> - <span>勾选用户</span> - </div> - <div class="info error-info">Message: element click intercepted: Element <span class="el-checkbox__inner"></span> is not clickable at point (212, 189). Other element would receive the click: <div data-v-2c75ef36="" class="el-dialog__wrapper" style="z-index: 2001;">...</div> - (Session info: MicrosoftEdge=131.0.2903.146) -Stacktrace: - (No symbol) [0x00007FF6CD606B05] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD92F444+1437348] - sqlite3_dbdata_init [0x00007FF6CD9D2D76+643174] - (No symbol) [0x00007FF6CD532E8A] - (No symbol) [0x00007FF6CD530FEC] - (No symbol) [0x00007FF6CD52EC27] - (No symbol) [0x00007FF6CD52DF29] - (No symbol) [0x00007FF6CD523EB3] - (No symbol) [0x00007FF6CD54C19A] - (No symbol) [0x00007FF6CD523437] - (No symbol) [0x00007FF6CD5232FD] - (No symbol) [0x00007FF6CD54C480] - (No symbol) [0x00007FF6CD523437] - (No symbol) [0x00007FF6CD566BFF] - (No symbol) [0x00007FF6CD54BE03] - (No symbol) [0x00007FF6CD522984] - (No symbol) [0x00007FF6CD521E30] - (No symbol) [0x00007FF6CD522571] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DBAD4+1094964] - (No symbol) [0x00007FF6CD6432B8] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DAF13+1091955] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DAA79+1090777] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6E0C81+461569] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6DC9A4+444452] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6DCAE9+444777] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6D2166+401382] - BaseThreadInitThunk [0x00007FFFDD52259D+29] - RtlUserThreadStart [0x00007FFFDF26AF38+40] - -Traceback: - File "D:\GithubData\自动化\ubains-module-test\运维集控\项目测试\运维标准版\cases\02用户管理\04删除用户.py", line 22, in teststeps - select_click.click() - File "C:\Users\29194\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\webelement.py", line 94, in click - self._execute(Command.CLICK_ELEMENT) - File "C:\Users\29194\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\webelement.py", line 395, in _execute - return self._parent.execute(command, params) - File "C:\Users\29194\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 384, in execute - self.error_handler.check_response(response) - File "C:\Users\29194\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 232, in check_response - raise exception_class(message, screen, stacktrace) -selenium.common.exceptions.ElementClickInterceptedException: Message: element click intercepted: Element <span class="el-checkbox__inner"></span> is not clickable at point (212, 189). Other element would receive the click: <div data-v-2c75ef36="" class="el-dialog__wrapper" style="z-index: 2001;">...</div> - (Session info: MicrosoftEdge=131.0.2903.146) -Stacktrace: - (No symbol) [0x00007FF6CD606B05] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD92F444+1437348] - sqlite3_dbdata_init [0x00007FF6CD9D2D76+643174] - (No symbol) [0x00007FF6CD532E8A] - (No symbol) [0x00007FF6CD530FEC] - (No symbol) [0x00007FF6CD52EC27] - (No symbol) [0x00007FF6CD52DF29] - (No symbol) [0x00007FF6CD523EB3] - (No symbol) [0x00007FF6CD54C19A] - (No symbol) [0x00007FF6CD523437] - (No symbol) [0x00007FF6CD5232FD] - (No symbol) [0x00007FF6CD54C480] - (No symbol) [0x00007FF6CD523437] - (No symbol) [0x00007FF6CD566BFF] - (No symbol) [0x00007FF6CD54BE03] - (No symbol) [0x00007FF6CD522984] - (No symbol) [0x00007FF6CD521E30] - (No symbol) [0x00007FF6CD522571] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DBAD4+1094964] - (No symbol) [0x00007FF6CD6432B8] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DAF13+1091955] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DAA79+1090777] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6E0C81+461569] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6DC9A4+444452] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6DCAE9+444777] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6D2166+401382] - BaseThreadInitThunk [0x00007FFFDD52259D+29] - RtlUserThreadStart [0x00007FFFDF26AF38+40] - -</div> - </div> - </div> - </div> - </div> - <div class="suite_dir" id="suite_dir cases\03区域分组\"> - <div> - <span class="label">进入目录</span> - <span>cases\03区域分组\</span> - </div> - <div class="suite_setup setup fail" id="suite_setup setup cases\03区域分组\"> - <div class="folder_header"> - <span class="label">套件初始化</span> - <span>cases\03区域分组\</span> - <span class="executetime">2025-01-14 17:51:42</span> - </div> - <div class="folder_body"> - <div class="info error-info">suite setup fail | Message: element click intercepted: Element <li data-v-b723143a="" role="menuitem" tabindex="-1" class="el-menu-item" style="padding-left: 40px;">...</li> is not clickable at point (95, 608). Other element would receive the click: <div data-v-2c75ef36="" class="el-dialog__wrapper" style="z-index: 2001;">...</div> - (Session info: MicrosoftEdge=131.0.2903.146) -Stacktrace: - (No symbol) [0x00007FF6CD606B05] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD92F444+1437348] - sqlite3_dbdata_init [0x00007FF6CD9D2D76+643174] - (No symbol) [0x00007FF6CD532E8A] - (No symbol) [0x00007FF6CD530FEC] - (No symbol) [0x00007FF6CD52EC27] - (No symbol) [0x00007FF6CD52DF29] - (No symbol) [0x00007FF6CD523EB3] - (No symbol) [0x00007FF6CD54C19A] - (No symbol) [0x00007FF6CD523437] - (No symbol) [0x00007FF6CD5232FD] - (No symbol) [0x00007FF6CD54C480] - (No symbol) [0x00007FF6CD523437] - (No symbol) [0x00007FF6CD566BFF] - (No symbol) [0x00007FF6CD54BE03] - (No symbol) [0x00007FF6CD522984] - (No symbol) [0x00007FF6CD521E30] - (No symbol) [0x00007FF6CD522571] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DBAD4+1094964] - (No symbol) [0x00007FF6CD6432B8] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DAF13+1091955] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DAA79+1090777] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6E0C81+461569] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6DC9A4+444452] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6DCAE9+444777] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6D2166+401382] - BaseThreadInitThunk [0x00007FFFDD52259D+29] - RtlUserThreadStart [0x00007FFFDF26AF38+40] - -Traceback: - File "D:\GithubData\自动化\ubains-module-test\运维集控\项目测试\运维标准版\cases\03区域分组\__st__.py", line 11, in suite_setup - enter_areagroup_manage() - File "D:\GithubData\自动化\ubains-module-test\运维集控\项目测试\运维标准版\lib\base.py", line 158, in enter_areagroup_manage - enter_areagroup_mag.click() - File "C:\Users\29194\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\webelement.py", line 94, in click - self._execute(Command.CLICK_ELEMENT) - File "C:\Users\29194\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\webelement.py", line 395, in _execute - return self._parent.execute(command, params) - File "C:\Users\29194\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 384, in execute - self.error_handler.check_response(response) - File "C:\Users\29194\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 232, in check_response - raise exception_class(message, screen, stacktrace) -selenium.common.exceptions.ElementClickInterceptedException: Message: element click intercepted: Element <li data-v-b723143a="" role="menuitem" tabindex="-1" class="el-menu-item" style="padding-left: 40px;">...</li> is not clickable at point (95, 608). Other element would receive the click: <div data-v-2c75ef36="" class="el-dialog__wrapper" style="z-index: 2001;">...</div> - (Session info: MicrosoftEdge=131.0.2903.146) -Stacktrace: - (No symbol) [0x00007FF6CD606B05] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD92F444+1437348] - sqlite3_dbdata_init [0x00007FF6CD9D2D76+643174] - (No symbol) [0x00007FF6CD532E8A] - (No symbol) [0x00007FF6CD530FEC] - (No symbol) [0x00007FF6CD52EC27] - (No symbol) [0x00007FF6CD52DF29] - (No symbol) [0x00007FF6CD523EB3] - (No symbol) [0x00007FF6CD54C19A] - (No symbol) [0x00007FF6CD523437] - (No symbol) [0x00007FF6CD5232FD] - (No symbol) [0x00007FF6CD54C480] - (No symbol) [0x00007FF6CD523437] - (No symbol) [0x00007FF6CD566BFF] - (No symbol) [0x00007FF6CD54BE03] - (No symbol) [0x00007FF6CD522984] - (No symbol) [0x00007FF6CD521E30] - (No symbol) [0x00007FF6CD522571] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DBAD4+1094964] - (No symbol) [0x00007FF6CD6432B8] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DAF13+1091955] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DAA79+1090777] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6E0C81+461569] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6DC9A4+444452] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6DCAE9+444777] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6D2166+401382] - BaseThreadInitThunk [0x00007FFFDD52259D+29] - RtlUserThreadStart [0x00007FFFDF26AF38+40] - -</div> - </div> - </div> - </div> - <div class="suite_dir" id="suite_dir cases\04区域类型\"> - <div> - <span class="label">进入目录</span> - <span>cases\04区域类型\</span> - </div> - <div class="suite_setup setup fail" id="suite_setup setup cases\04区域类型\"> - <div class="folder_header"> - <span class="label">套件初始化</span> - <span>cases\04区域类型\</span> - <span class="executetime">2025-01-14 17:51:43</span> - </div> - <div class="folder_body"> - <div class="info error-info">suite setup fail | Message: element click intercepted: Element <li data-v-b723143a="" role="menuitem" tabindex="-1" class="el-menu-item" style="padding-left: 40px;">...</li> is not clickable at point (95, 658). Other element would receive the click: <div data-v-2c75ef36="" class="el-dialog__wrapper" style="z-index: 2001;">...</div> - (Session info: MicrosoftEdge=131.0.2903.146) -Stacktrace: - (No symbol) [0x00007FF6CD606B05] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD92F444+1437348] - sqlite3_dbdata_init [0x00007FF6CD9D2D76+643174] - (No symbol) [0x00007FF6CD532E8A] - (No symbol) [0x00007FF6CD530FEC] - (No symbol) [0x00007FF6CD52EC27] - (No symbol) [0x00007FF6CD52DF29] - (No symbol) [0x00007FF6CD523EB3] - (No symbol) [0x00007FF6CD54C19A] - (No symbol) [0x00007FF6CD523437] - (No symbol) [0x00007FF6CD5232FD] - (No symbol) [0x00007FF6CD54C480] - (No symbol) [0x00007FF6CD523437] - (No symbol) [0x00007FF6CD566BFF] - (No symbol) [0x00007FF6CD54BE03] - (No symbol) [0x00007FF6CD522984] - (No symbol) [0x00007FF6CD521E30] - (No symbol) [0x00007FF6CD522571] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DBAD4+1094964] - (No symbol) [0x00007FF6CD6432B8] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DAF13+1091955] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DAA79+1090777] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6E0C81+461569] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6DC9A4+444452] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6DCAE9+444777] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6D2166+401382] - BaseThreadInitThunk [0x00007FFFDD52259D+29] - RtlUserThreadStart [0x00007FFFDF26AF38+40] - -Traceback: - File "D:\GithubData\自动化\ubains-module-test\运维集控\项目测试\运维标准版\cases\04区域类型\__st__.py", line 11, in suite_setup - enter_areatype_manage() - File "D:\GithubData\自动化\ubains-module-test\运维集控\项目测试\运维标准版\lib\base.py", line 173, in enter_areatype_manage - enter_areatype_mag.click() - File "C:\Users\29194\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\webelement.py", line 94, in click - self._execute(Command.CLICK_ELEMENT) - File "C:\Users\29194\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\webelement.py", line 395, in _execute - return self._parent.execute(command, params) - File "C:\Users\29194\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 384, in execute - self.error_handler.check_response(response) - File "C:\Users\29194\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 232, in check_response - raise exception_class(message, screen, stacktrace) -selenium.common.exceptions.ElementClickInterceptedException: Message: element click intercepted: Element <li data-v-b723143a="" role="menuitem" tabindex="-1" class="el-menu-item" style="padding-left: 40px;">...</li> is not clickable at point (95, 658). Other element would receive the click: <div data-v-2c75ef36="" class="el-dialog__wrapper" style="z-index: 2001;">...</div> - (Session info: MicrosoftEdge=131.0.2903.146) -Stacktrace: - (No symbol) [0x00007FF6CD606B05] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD92F444+1437348] - sqlite3_dbdata_init [0x00007FF6CD9D2D76+643174] - (No symbol) [0x00007FF6CD532E8A] - (No symbol) [0x00007FF6CD530FEC] - (No symbol) [0x00007FF6CD52EC27] - (No symbol) [0x00007FF6CD52DF29] - (No symbol) [0x00007FF6CD523EB3] - (No symbol) [0x00007FF6CD54C19A] - (No symbol) [0x00007FF6CD523437] - (No symbol) [0x00007FF6CD5232FD] - (No symbol) [0x00007FF6CD54C480] - (No symbol) [0x00007FF6CD523437] - (No symbol) [0x00007FF6CD566BFF] - (No symbol) [0x00007FF6CD54BE03] - (No symbol) [0x00007FF6CD522984] - (No symbol) [0x00007FF6CD521E30] - (No symbol) [0x00007FF6CD522571] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DBAD4+1094964] - (No symbol) [0x00007FF6CD6432B8] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DAF13+1091955] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DAA79+1090777] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6E0C81+461569] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6DC9A4+444452] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6DCAE9+444777] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6D2166+401382] - BaseThreadInitThunk [0x00007FFFDD52259D+29] - RtlUserThreadStart [0x00007FFFDF26AF38+40] - -</div> - </div> - </div> - </div> - <div class="suite_dir" id="suite_dir cases\05区域功能\"> - <div> - <span class="label">进入目录</span> - <span>cases\05区域功能\</span> - </div> - <div class="suite_setup setup fail" id="suite_setup setup cases\05区域功能\"> - <div class="folder_header"> - <span class="label">套件初始化</span> - <span>cases\05区域功能\</span> - <span class="executetime">2025-01-14 17:51:44</span> - </div> - <div class="folder_body"> - <div class="info error-info">suite setup fail | Message: element click intercepted: Element <li data-v-b723143a="" role="menuitem" tabindex="-1" class="el-menu-item" style="padding-left: 40px;">...</li> is not clickable at point (95, 708). Other element would receive the click: <div data-v-2c75ef36="" class="el-dialog__wrapper" style="z-index: 2001;">...</div> - (Session info: MicrosoftEdge=131.0.2903.146) -Stacktrace: - (No symbol) [0x00007FF6CD606B05] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD92F444+1437348] - sqlite3_dbdata_init [0x00007FF6CD9D2D76+643174] - (No symbol) [0x00007FF6CD532E8A] - (No symbol) [0x00007FF6CD530FEC] - (No symbol) [0x00007FF6CD52EC27] - (No symbol) [0x00007FF6CD52DF29] - (No symbol) [0x00007FF6CD523EB3] - (No symbol) [0x00007FF6CD54C19A] - (No symbol) [0x00007FF6CD523437] - (No symbol) [0x00007FF6CD5232FD] - (No symbol) [0x00007FF6CD54C480] - (No symbol) [0x00007FF6CD523437] - (No symbol) [0x00007FF6CD566BFF] - (No symbol) [0x00007FF6CD54BE03] - (No symbol) [0x00007FF6CD522984] - (No symbol) [0x00007FF6CD521E30] - (No symbol) [0x00007FF6CD522571] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DBAD4+1094964] - (No symbol) [0x00007FF6CD6432B8] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DAF13+1091955] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DAA79+1090777] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6E0C81+461569] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6DC9A4+444452] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6DCAE9+444777] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6D2166+401382] - BaseThreadInitThunk [0x00007FFFDD52259D+29] - RtlUserThreadStart [0x00007FFFDF26AF38+40] - -Traceback: - File "D:\GithubData\自动化\ubains-module-test\运维集控\项目测试\运维标准版\cases\05区域功能\__st__.py", line 11, in suite_setup - enter_areafuntion_manage() - File "D:\GithubData\自动化\ubains-module-test\运维集控\项目测试\运维标准版\lib\base.py", line 188, in enter_areafuntion_manage - enter_areafuntion_mag.click() - File "C:\Users\29194\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\webelement.py", line 94, in click - self._execute(Command.CLICK_ELEMENT) - File "C:\Users\29194\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\webelement.py", line 395, in _execute - return self._parent.execute(command, params) - File "C:\Users\29194\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 384, in execute - self.error_handler.check_response(response) - File "C:\Users\29194\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 232, in check_response - raise exception_class(message, screen, stacktrace) -selenium.common.exceptions.ElementClickInterceptedException: Message: element click intercepted: Element <li data-v-b723143a="" role="menuitem" tabindex="-1" class="el-menu-item" style="padding-left: 40px;">...</li> is not clickable at point (95, 708). Other element would receive the click: <div data-v-2c75ef36="" class="el-dialog__wrapper" style="z-index: 2001;">...</div> - (Session info: MicrosoftEdge=131.0.2903.146) -Stacktrace: - (No symbol) [0x00007FF6CD606B05] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD92F444+1437348] - sqlite3_dbdata_init [0x00007FF6CD9D2D76+643174] - (No symbol) [0x00007FF6CD532E8A] - (No symbol) [0x00007FF6CD530FEC] - (No symbol) [0x00007FF6CD52EC27] - (No symbol) [0x00007FF6CD52DF29] - (No symbol) [0x00007FF6CD523EB3] - (No symbol) [0x00007FF6CD54C19A] - (No symbol) [0x00007FF6CD523437] - (No symbol) [0x00007FF6CD5232FD] - (No symbol) [0x00007FF6CD54C480] - (No symbol) [0x00007FF6CD523437] - (No symbol) [0x00007FF6CD566BFF] - (No symbol) [0x00007FF6CD54BE03] - (No symbol) [0x00007FF6CD522984] - (No symbol) [0x00007FF6CD521E30] - (No symbol) [0x00007FF6CD522571] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DBAD4+1094964] - (No symbol) [0x00007FF6CD6432B8] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DAF13+1091955] - Microsoft::Applications::Events::EventProperty::empty [0x00007FF6CD8DAA79+1090777] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6E0C81+461569] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6DC9A4+444452] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6DCAE9+444777] - Microsoft::Applications::Events::ILogConfiguration::operator* [0x00007FF6CD6D2166+401382] - BaseThreadInitThunk [0x00007FFFDD52259D+29] - RtlUserThreadStart [0x00007FFFDF26AF38+40] - -</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-01-14 17:51:45</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("body").scrollIntoView()">页首</div> - <div class="menu-item" onclick="window.open("http://www.byhy.net/tut/auto/hytest/01", "_blank"); ">帮助</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 Index: 统一平台/base/driver_setup.py IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/统一平台/base/driver_setup.py b/统一平台/base/driver_setup.py new file mode 100644 --- /dev/null (date 1742436531437) +++ b/统一平台/base/driver_setup.py (date 1742436531437) @@ -0,0 +1,61 @@ + + + +# 浏览器初始化函数 +def browser_init(login_type): + """ + 初始化浏览器设置和实例。 + + 此函数旨在创建并配置一个Chrome浏览器实例,包括设置Chrome选项以排除不必要的日志, + 并尝试打开特定的登录页面。任何初始化过程中出现的错误都会被捕获并记录。 + + 参数: + login_type (str): 指定登录类型,根据不同的登录类型选择不同的URL。 + + 返回: + 无 + """ + # 标记初始化过程的开始 + INFO("'----------' 正在初始化浏览器 '----------'") + + # 创建Chrome选项实例,用于配置浏览器行为 + options = webdriver.ChromeOptions() + # 添加实验性选项,排除某些命令行开关以减少输出日志 + options.add_experimental_option('excludeSwitches', ['enable-Logging']) + # 忽略证书错误,允许在本地主机上运行时不安全 + options.add_argument('--ignore-certificate-errors') + # 禁用自动化控制特征检测,避免被网站识别为自动化流量 + options.add_argument('--disable-blink-features=AutomationControlled') + # 允许不安全的本地主机运行,通常用于开发和测试环境 + options.add_argument('--allow-insecure-localhost') + + # 使用webdriver_manager自动下载并管理chromedriver + # service = ChromeService(ChromeDriverManager().install()) + # 使用备用的ChromeDriver下载源 + # service = Service(ChromeDriverManager().install()) + # 手动指定ChromeDriver的路径 + # 自动化运行服务器的chromedriver路径: + service = Service(r'C:\Users\29194\AppData\Local\Programs\Python\Python310\Scripts\chromedriver.exe') + # service = Service(r'C:\Program Files\Python310\Scripts\chromedriver.exe') + # 尝试创建WebDriver实例并执行初始化操作 + try: + # 创建WebDriver实例 + wd = webdriver.Chrome(service=service, options=options) + # 设置隐式等待时间为10秒,以允许元素加载 + wd.implicitly_wait(60) + + # 获取登录URL + login_url = get_login_url_from_config(login_type) + # 打开对应类型的登录页面 + wd.get(login_url) + # 最大化浏览器窗口 + wd.maximize_window() + + # 将WebDriver实例存储在全局存储器中,以便后续使用 + GSTORE['wd'] = wd + # 标记初始化过程完成 + INFO("'----------' 浏览器初始化完成 '----------'") + except Exception as e: + # 捕获并记录初始化过程中的任何异常 + logging.error(f"浏览器初始化失败:{e}") + Index: 运维集控/项目测试/运维标准版/cases/07类型标签/01新增标签.py IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/运维集控/项目测试/运维标准版/cases/07类型标签/01新增标签.py b/运维集控/项目测试/运维标准版/cases/07类型标签/01新增标签.py new file mode 100644 --- /dev/null (date 1741834618353) +++ b/运维集控/项目测试/运维标准版/cases/07类型标签/01新增标签.py (date 1741834618353) @@ -0,0 +1,85 @@ +import sys +import os + +from hytest.common import SELENIUM_LOG_SCREEN + +sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', '..', '..', '..'))) +from 运维集控.项目测试.运维标准版.lib.base import * + +#构建当前项目路径 +sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', '..', '..', '..'))) +# 构建 CSV 文件的绝对路径 +csv_path = os.path.abspath( + os.path.join(os.path.dirname(__file__), '..', '..', 'testdata', '03类型标签', '新增标签.csv')) + +class AreagroupAdd: + tag = ['新增类型标签'] + ddt_cases = read_csv_data(csv_path) + def teststeps(self): + wd = GSTORE['wd'] + # 从self.para中解构出数据 + name = self.name + area_group, group_name, group_address, remark, info = self.para + + STEP(1, '点击新增按钮') + areagroup_add = WebDriverWait(wd, 10).until( + EC.element_to_be_clickable((By.XPATH, "//div[@class='company-edmit-right']//span[contains(text(),'新增')]")) + ) + areagroup_add.click() + + STEP(2, f'查看并选择类型标签:{area_group}') + if area_group: + area_group_input = WebDriverWait(wd, 10).until( + EC.presence_of_element_located((By.XPATH, "// input[ @ placeholder = '请选择分组']")) + ) + area_group_input.clear() + area_group_input.send_keys(area_group) + sleep(1) + #默认选择第一个内容 + area_group_select = WebDriverWait(wd, 10).until( + EC.presence_of_element_located((By.XPATH, "//div[@class='el-cascader__suggestion-panel el-scrollbar']//li[1]//span[1]")) + ) + area_group_select.click() + else: + print("group_name 为空,不执行选择区域分组的操作") + + STEP(3, f'填写标签名称:{group_name}') + group_name_input = WebDriverWait(wd, 10).until( + EC.presence_of_element_located((By.XPATH, "//input[@placeholder='长度1-20个字符']")) + ) + group_name_input.clear() + group_name_input.send_keys(group_name) + + STEP(4, f'填写标签排序:{group_address}') + group_address_input = WebDriverWait(wd, 10).until( + EC.presence_of_element_located((By.XPATH, "//input[@placeholder='输入地址不能大于50个字符']")) + ) + group_address_input.clear() + group_address_input.send_keys(group_address) + + STEP(5, f'填写分组备注:{remark}') + group_remark = WebDriverWait(wd, 10).until( + EC.presence_of_element_located( + (By.XPATH, "//input[@placeholder='请输入备注']")) + ) + group_remark.clear() + group_remark.send_keys(remark) + + STEP(6, '点击确认') + commit = WebDriverWait(wd, 10).until( + EC.element_to_be_clickable((By.XPATH, "//div[@class='dialog-footer']//span[contains(text(),'确 定')]")) + ) + commit.click() + + STEP(7, '验证是否新增成功') + get_menu = WebDriverWait(wd, 10).until( + EC.visibility_of_element_located((By.XPATH, "//p[@class='el-message__content']")) + ) + get_menu1 = get_menu.text + CHECK_POINT('检查是否出现成功提示弹窗', get_menu1 == info ) + + # 截图并保存 + SELENIUM_LOG_SCREEN(wd, "50%") + sleep(1) + wd.refresh() + Index: 运维集控/项目测试/运维标准版/cases/08设备管理/01新增设备.py IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/运维集控/项目测试/运维标准版/cases/08设备管理/01新增设备.py b/运维集控/项目测试/运维标准版/cases/08设备管理/01新增设备.py new file mode 100644 --- /dev/null (date 1741834618363) +++ b/运维集控/项目测试/运维标准版/cases/08设备管理/01新增设备.py (date 1741834618363) @@ -0,0 +1,108 @@ +import sys +import os + +from hytest.common import SELENIUM_LOG_SCREEN + +sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', '..', '..', '..'))) +from 运维集控.项目测试.运维标准版.lib.base import * + +# 构建 CSV 文件的绝对路径 +csv_path = os.path.abspath( + os.path.join(os.path.dirname(__file__), '..', '..', 'testdata', '08设备管理', '新增设备.csv')) + +class AreafuntionAdd: + tag = ['新增设备'] + ddt_cases = read_csv_data(csv_path) + def teststeps(self): + wd = GSTORE['wd'] + + #从self.para中解构出数据 + name = self.name + area_group, area_type, area_name, area_ip, remark, info = self.para + + STEP(1, '点击新增按钮') + areafuntion_add = WebDriverWait(wd, 10).until( + EC.element_to_be_clickable( + (By.XPATH, "//div[@class='company-edmit-right']//span[contains(text(),'新增')]")) + ) + areafuntion_add.click() + sleep(1) + + STEP(2, f'查找并选择区域分组:{area_group}') + if area_group: + area_group_input = WebDriverWait(wd, 10).until( + EC.presence_of_element_located( + (By.XPATH, "//div[@class='dialog_input']//input[@placeholder='请选择分组']")) + ) + area_group_input.send_keys(area_group) + #默认选择第一个分组 + areagroup_select = WebDriverWait(wd, 10).until( + EC.presence_of_element_located( + ( + By.XPATH, "//li[@class='el-cascader__suggestion-item']")) + ) + sleep(1) + areagroup_select.click() + else: + print("group_name 为空,不执行选择区域分组的操作") + + STEP(3, f'选择区域类型:{area_type}') + if area_type: + area_type_input = WebDriverWait(wd, 10).until( + EC.presence_of_element_located( + (By.XPATH, "//div[@class='dialog_input']//input[@placeholder='请选择区域类型']")) + ) + area_type_input.send_keys(area_type) + #默认选择第一个区域类型 + areatype_select = WebDriverWait(wd, 10).until( + EC.presence_of_element_located( + (By.XPATH, "//div[@x-placement='bottom-start']//ul[@class='el-scrollbar__view el-select-dropdown__list']")) + ) + sleep(1) + areatype_select.click() + else: + print("area_type 为空,不执行选择区域类型的操作") + + STEP(4, f'输入区域名称:{area_name}') + area_name_input = WebDriverWait(wd, 10).until( + EC.presence_of_element_located( + (By.XPATH, "//div[contains(@class,'dialog_input')]//input[contains(@placeholder,'请输入区域名称')]")) + ) + area_name_input.clear() + area_name_input.send_keys(area_name) + + STEP(5, f'填写IP地址:{area_ip}') + area_ip_input = WebDriverWait(wd, 10).until( + EC.presence_of_element_located( + (By.XPATH, "//input[@placeholder='IP地址']")) + ) + area_ip_input.clear() + area_ip_input.send_keys(area_ip) + + STEP(6, f'填写备注:{remark}') + funtion_remark = WebDriverWait(wd, 10).until( + EC.presence_of_element_located( + (By.XPATH, "//input[@placeholder='备注']")) + ) + funtion_remark.clear() + funtion_remark.send_keys(remark) + + STEP(7, '点击确认') + commit = WebDriverWait(wd, 10).until( + EC.element_to_be_clickable( + (By.XPATH, "//div[@aria-label='新增']//span[contains(text(),'确 定')]")) + ) + commit.click() + + STEP(8, '验证是否新增成功') + get_menu = WebDriverWait(wd, 10).until( + EC.visibility_of_element_located( + (By.CSS_SELECTOR, '.el-message__content')) + ) + get_menu1 = get_menu.text + CHECK_POINT('检查是否出现成功提示弹窗', get_menu1 == info) + + # 截图并保存 + SELENIUM_LOG_SCREEN(wd, "50%") + sleep(1) + wd.refresh() \ No newline at end of file Index: 运维集控/项目测试/运维标准版/testdata/07类型标签/新增标签.csv IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/运维集控/项目测试/运维标准版/testdata/07类型标签/新增标签.csv b/运维集控/项目测试/运维标准版/testdata/07类型标签/新增标签.csv --- a/运维集控/项目测试/运维标准版/testdata/07类型标签/新增标签.csv (revision 1114284965c773bf063d20e1486fe7c5aa398274) +++ b/运维集控/项目测试/运维标准版/testdata/07类型标签/新增标签.csv (date 1741834618390) @@ -1,0 +1,11 @@ +name,typename,sort +新增标签-001-标签名称为空,,1 +新增标签-002-排序为空,智慧大屏1, +新增标签-003-排序为小数,智慧大屏2,1.1 +新增标签-004-排序为负数,智慧大屏3,-1 +新增标签-005-正常新增标签1,智慧屏设备,1 +新增标签-006-正常新增标签2,时序电源,2 +新增标签-007-正常新增标签3,中控主机,3 +新增标签-008-正常新增标签4,音频处理器,4 +新增标签-009-正常新增标签5,视频处理器,5 +新增标签-010-正常新增标签6,网络路由,6 Index: 运维集控/项目测试/运维标准版/lib/base.py IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.BaseRevisionTextPatchEP <+>import pandas as pd\r\nimport csv\r\nimport urllib\r\nimport glob\r\nimport subprocess\r\nimport requests\r\nimport json\r\nimport hmac\r\nimport hashlib\r\nimport base64\r\nimport time\r\nimport win32api\r\nimport win32con\r\nimport win32gui\r\nimport logging\r\nfrom hytest import *\r\nimport pandas as pd\r\nfrom selenium import webdriver\r\nfrom datetime import datetime\r\nfrom urllib.parse import urlencode\r\nfrom selenium.webdriver.common.by import By\r\nfrom selenium.webdriver.edge.options import Options\r\nfrom selenium.webdriver.support.wait import WebDriverWait\r\nfrom selenium.webdriver.support import expected_conditions as EC\r\nfrom selenium.common import TimeoutException,ElementNotInteractableException\r\nfrom selenium.webdriver.common.keys import Keys\r\nfrom time import sleep\r\n\r\nlogging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')\r\n# 打开浏览器,忽略ssh警告\r\ndef open_browser():\r\n INFO('打开默认浏览器')\r\n # 更改显示屏分辨率为1920x1080\r\n # success = change_resolution(1280, 1024)\r\n success = change_resolution(1920, 1080)\r\n edge_options = Options()\r\n edge_options.add_argument('--ignore-certificate-errors')\r\n edge_options.add_argument('--disable-blink-features=AutomationControlled')\r\n edge_options.add_argument('--allow-insecure-localhost')\r\n wd = webdriver.Edge(options=edge_options)\r\n GSTORE['wd'] = wd\r\n # wd.get('https://rms.ubainsyun.com/#/login')\r\n wd.get('https://192.168.5.218:8443/#/login')\r\n wd.maximize_window()\r\n wd.implicitly_wait(10)\r\n\r\n# 定义调整屏幕分辨率,仅内部环境跑定时任务需要使用。\r\ndef change_resolution(width, height):\r\n # 获取当前显示器的设备上下文(Device Context, DC)\r\n device = win32api.EnumDisplayDevices(None, 0)\r\n dm = win32api.EnumDisplaySettings(device.DeviceName, win32con.ENUM_CURRENT_SETTINGS)\r\n\r\n if dm.PelsWidth != width or dm.PelsHeight != height:\r\n print(f\"Changing resolution to {width}x{height}\")\r\n dm.PelsWidth = width\r\n dm.PelsHeight = height\r\n\r\n # CDS_TEST 是测试模式,如果设置成功则不实际应用更改\r\n if win32api.ChangeDisplaySettings(dm, win32con.CDS_TEST) != win32con.DISP_CHANGE_SUCCESSFUL :\r\n print(\"The requested resolution change is not supported.\")\r\n return False\r\n\r\n # 实际应用新的分辨率设置\r\n if win32api.ChangeDisplaySettings(dm, 0) != win32con.DISP_CHANGE_SUCCESSFUL:\r\n print(\"Failed to change resolution.\")\r\n return False\r\n\r\n print(\"Resolution changed successfully.\")\r\n return True\r\n else:\r\n print(\"The requested resolution is already set.\")\r\n return True\r\n\r\n# 用户进行登录\r\ndef user_login(username, password, captcha):\r\n wd = GSTORE['wd']\r\n INFO(f'输入登录账号: {username}')\r\n username_input = WebDriverWait(wd, 10).until(\r\n EC.presence_of_element_located((By.XPATH, \"//input[@placeholder='请输入登录账号']\"))\r\n )\r\n username_input.clear()\r\n username_input.send_keys(username)\r\n\r\n INFO(f'输入登录密码: {password}')\r\n password_input = WebDriverWait(wd, 10).until(\r\n EC.presence_of_element_located((By.XPATH, \"//input[@placeholder='请输入登录密码']\"))\r\n )\r\n password_input.clear()\r\n password_input.send_keys(password)\r\n\r\n INFO(f'输入验证码:{captcha}')\r\n captcha_input = WebDriverWait(wd, 10).until(\r\n EC.presence_of_element_located((By.XPATH, \"//input[@placeholder='请输入验证码(区分大小写)']\"))\r\n )\r\n captcha_input.clear()\r\n captcha_input.send_keys(captcha)\r\n\r\n INFO('点击登录按钮')\r\n login_button = WebDriverWait(wd, 3).until(\r\n EC.element_to_be_clickable((By.XPATH, \"//div[@class='loginButton']\"))\r\n )\r\n login_button.click()\r\n sleep(1)\r\n\r\ndef validate_input(username, password, captcha):\r\n if not isinstance(username, str) or not isinstance(password, str) or not isinstance(captcha, str):\r\n raise ValueError(\"Invalid input type\")\r\n if len(username) < 1 or len(password) < 1 or len(captcha) < 1:\r\n raise ValueError(\"Input cannot be empty\")\r\n\r\ndef run_login_tests(df):\r\n # 遍历每一行\r\n for index, row in df.iterrows():\r\n username = row.get('username', None)\r\n password = row.get('password', None)\r\n captcha = row.get('captcha', None)\r\n if username and password and captcha:\r\n try:\r\n validate_input(username, password, captcha)\r\n user_login(username, password, captcha)\r\n except ValueError as e:\r\n print(f\"Invalid input at row {index}: {e}\")\r\n\r\n# 构建当前所在目录\r\ndef main():\r\n # 获取当前脚本的目录\r\n current_dir = os.path.dirname(os.path.abspath(__file__))\r\n csv_file_path = os.path.join(current_dir, '../testdata/01登录模块/登录信息.csv')\r\n try:\r\n if not os.path.exists(csv_file_path):\r\n print(f\"File not found: {csv_file_path}\")\r\n return\r\n df = pd.read_csv(csv_file_path, encoding='utf-8')\r\n run_login_tests(df)\r\n except Exception as e:\r\n print(f\"An error occurred: {e}\")\r\n\r\n# 进入后台管理系统页面\r\ndef enter_system():\r\n wd = GSTORE['wd']\r\n if wd is None:\r\n raise ValueError(\"WebDriver is not initialized\")\r\n\r\n logging.info('点击系统设置按钮')\r\n try:\r\n enter_sys = WebDriverWait(wd, 10).until(\r\n EC.element_to_be_clickable((By.XPATH, \"//li[contains(text(),'系统设置')]\"))\r\n )\r\n enter_sys.click()\r\n logging.info('系统设置按钮已点击')\r\n except (TimeoutException, ElementNotInteractableException) as error:\r\n logging.error(f\"Error clicking system settings button: {error}\")\r\n\r\n# 进入管理页面\r\ndef enter_manage():\r\n wd = GSTORE['wd']\r\n if wd is None:\r\n raise ValueError(\"WebDriver is not initialized\")\r\n\r\n logging.info('点击管理按钮')\r\n try:\r\n enter_mag = WebDriverWait(wd, 10).until(\r\n EC.element_to_be_clickable((By.XPATH, \"//div[@class='el-submenu__title']//span[contains(text(),'管理')]\"))\r\n )\r\n enter_mag.click()\r\n logging.info('管理按钮已点击')\r\n except (TimeoutException, ElementNotInteractableException) as error:\r\n logging.error(f\"Error clicking manage button: {error}\")\r\n\r\n# 进入用户管理页面\r\ndef enter_user_manage():\r\n wd = GSTORE['wd']\r\n if wd is None:\r\n raise ValueError(\"WebDriver is not initialized\")\r\n\r\n logging.info('点击用户管理按钮')\r\n try:\r\n enter_user_mag = WebDriverWait(wd, 10).until(\r\n EC.element_to_be_clickable((By.XPATH, \"//li[contains(text(),'用户管理')]\"))\r\n )\r\n enter_user_mag.click()\r\n logging.info('打开用户管理页面')\r\n except (TimeoutException, ElementNotInteractableException) as error:\r\n logging.error(f\"Error clicking manage button: {error}\")\r\n\r\n# 进入区域分组管理页面\r\ndef enter_areagroup_manage():\r\n wd = GSTORE['wd']\r\n if wd is None:\r\n raise ValueError(\"WebDriver is not initialized\")\r\n\r\n logging.info('点击区域分组按钮')\r\n try:\r\n enter_areagroup_mag = WebDriverWait(wd, 10).until(\r\n EC.element_to_be_clickable((By.XPATH, \"//li[contains(text(),'区域分组')]\"))\r\n )\r\n enter_areagroup_mag.click()\r\n logging.info('打开区域分组页面')\r\n except (TimeoutException, ElementNotInteractableException) as error:\r\n logging.error(f\"Error clicking manage button: {error}\")\r\n\r\n# 进入区域类型页面\r\ndef enter_areatype_manage():\r\n wd = GSTORE['wd']\r\n if wd is None:\r\n raise ValueError(\"WebDriver is not initialized\")\r\n\r\n logging.info('点击区域类型按钮')\r\n try:\r\n enter_areatype_mag = WebDriverWait(wd, 10).until(\r\n EC.element_to_be_clickable((By.XPATH, \"//li[contains(text(),'区域类型')]\"))\r\n )\r\n enter_areatype_mag.click()\r\n logging.info('打开区域类型页面')\r\n except (TimeoutException, ElementNotInteractableException) as error:\r\n logging.error(f\"Error clicking manage button: {error}\")\r\n\r\n# 进入区域功能页面\r\ndef enter_areafuntion_manage():\r\n wd = GSTORE['wd']\r\n if wd is None:\r\n raise ValueError(\"WebDriver is not initialized\")\r\n\r\n logging.info('点击区域功能按钮')\r\n try:\r\n enter_areafuntion_mag = WebDriverWait(wd, 10).until(\r\n EC.element_to_be_clickable((By.XPATH, \"//li[contains(text(),'区域功能')]\"))\r\n )\r\n enter_areafuntion_mag.click()\r\n logging.info('打开区域功能页面')\r\n except (TimeoutException, ElementNotInteractableException) as error:\r\n logging.error(f\"Error clicking manage button: {error}\")\r\n\r\n# 进入区域管理页面\r\ndef enter_area_manage():\r\n wd = GSTORE['wd']\r\n if wd is None:\r\n raise ValueError(\"WebDriver is not initialized\")\r\n\r\n logging.info('点击区域管理按钮')\r\n try:\r\n enter_area_mag = WebDriverWait(wd, 10).until(\r\n EC.element_to_be_clickable((By.XPATH, \"//li[contains(text(),'区域管理')]\"))\r\n )\r\n enter_area_mag.click()\r\n logging.info('打开区域管理页面')\r\n except (TimeoutException, ElementNotInteractableException) as error:\r\n logging.error(f\"Error clicking manage button: {error}\")\r\n\r\n# 进入类型标签页面\r\ndef enter_typetag():\r\n wd = GSTORE['wd']\r\n if wd is None:\r\n raise ValueError(\"WebDriver is not initialized\")\r\n\r\n logging.info('点击类型标签按钮')\r\n try:\r\n enter_type_tag = WebDriverWait(wd, 10).until(\r\n EC.element_to_be_clickable((By.XPATH, \"//li[contains(text(),'类型标签')]\"))\r\n )\r\n enter_type_tag.click()\r\n logging.info('打开类型标签页面')\r\n except (TimeoutException, ElementNotInteractableException) as error:\r\n logging.error(f\"Error clicking manage button: {error}\")\r\n\r\n# 进入设备管理页面\r\ndef enter_devices_manage():\r\n wd = GSTORE['wd']\r\n if wd is None:\r\n raise ValueError(\"WebDriver is not initialized\")\r\n\r\n logging.info('点击设备管理按钮')\r\n try:\r\n enter_devices_mag = WebDriverWait(wd, 10).until(\r\n EC.element_to_be_clickable((By.XPATH, \"//li[contains(text(),'设备管理')]\"))\r\n )\r\n enter_devices_mag.click()\r\n logging.info('打开设备管理页面')\r\n except (TimeoutException, ElementNotInteractableException) as error:\r\n logging.error(f\"Error clicking manage button: {error}\")\r\n\r\n# 进入协议管理页面\r\ndef enter_protocol_manage():\r\n wd = GSTORE['wd']\r\n if wd is None:\r\n raise ValueError(\"WebDriver is not initialized\")\r\n\r\n logging.info('点击协议管理按钮')\r\n try:\r\n enter_protocol_mag = WebDriverWait(wd, 10).until(\r\n EC.element_to_be_clickable((By.XPATH, \"//li[contains(text(),'协议管理')]\"))\r\n )\r\n enter_protocol_mag.click()\r\n logging.info('打开协议管理页面')\r\n except (TimeoutException, ElementNotInteractableException) as error:\r\n logging.error(f\"Error clicking manage button: {error}\")\r\n\r\n# 进入数据类型页面\r\ndef enter_datatype():\r\n wd = GSTORE['wd']\r\n if wd is None:\r\n raise ValueError(\"WebDriver is not initialized\")\r\n\r\n logging.info('点击数据类型按钮')\r\n try:\r\n enter_data_type = WebDriverWait(wd, 10).until(\r\n EC.element_to_be_clickable((By.XPATH, \"//li[contains(text(),'数据类型')]\"))\r\n )\r\n enter_data_type.click()\r\n logging.info('打开数据类型页面')\r\n except (TimeoutException, ElementNotInteractableException) as error:\r\n logging.error(f\"Error clicking manage button: {error}\")\r\n\r\n# 进入联动动作页面\r\ndef enter_linkaction():\r\n wd = GSTORE['wd']\r\n if wd is None:\r\n raise ValueError(\"WebDriver is not initialized\")\r\n\r\n logging.info('点击联动动作按钮')\r\n try:\r\n enter_link_action = WebDriverWait(wd, 10).until(\r\n EC.element_to_be_clickable((By.XPATH, \"//li[contains(text(),'联动动作')]\"))\r\n )\r\n enter_link_action.click()\r\n logging.info('打开联动动作页面')\r\n except (TimeoutException, ElementNotInteractableException) as error:\r\n logging.error(f\"Error clicking manage button: {error}\")\r\n\r\n# 进入模式管理页面\r\ndef enter_model_manage():\r\n wd = GSTORE['wd']\r\n if wd is None:\r\n raise ValueError(\"WebDriver is not initialized\")\r\n\r\n logging.info('点击模式管理按钮')\r\n try:\r\n enter_model_mag = WebDriverWait(wd, 10).until(\r\n EC.element_to_be_clickable((By.XPATH, \"//li[contains(text(),'模式管理')]\"))\r\n )\r\n enter_model_mag.click()\r\n logging.info('打开模式管理页面')\r\n except (TimeoutException, ElementNotInteractableException) as error:\r\n logging.error(f\"Error clicking manage button: {error}\")\r\n\r\n# 定义钉钉接口函数\r\ndef dingding_send_message(test_report_url, title, mobile, ding_type):\r\n \"\"\"\r\n 发送钉钉机器人消息\r\n 参考接口文档:https://open.dingtalk.com/document/orgapp/custom-robots-send-group-messages#title-7fs-kgs-36x\r\n\r\n :param test_report_url: 测试报告链接\r\n :param title: 消息标题\r\n :param text: 消息内容\r\n :param mobile: 需要@的手机号列表\r\n \"\"\"\r\n # 记录调用此函数的日志\r\n logging.info(\"开始构建并发送钉钉机器人消息\")\r\n # 钉钉机器人的 Webhook URL 和密钥(正式环境)\r\n # webhook_url = 'https://oapi.dingtalk.com/robot/send?access_token=b0eea0bbf097ce3badb4c832d2cd0267a50486f395ec8beca6e2042102bb295b'\r\n # secret = 'SEC928b11659c5fd6476cfa2042edbf56da876abf759289f7e4d3c671fb9a81bf43'\r\n # 钉钉机器人的 Webhook URL 和密钥(测试环境)\r\n\r\n if ding_type == '标准版巡检':\r\n webhook_url = 'https://oapi.dingtalk.com/robot/send?access_token=7fbf40798cad98b1b5db55ff844ba376b1816e80c5777e6f47ae1d9165dacbb4'\r\n secret = 'SEC610498ed6261ae2df1d071d0880aaa70abf5e67efe47f75a809c1f2314e0dbd6'\r\n elif ding_type == '展厅巡检':\r\n webhook_url = 'https://oapi.dingtalk.com/robot/send?access_token=061b6e9b1ae436f356cfda7fe19b6e58e46b62670046a78bd3a4d869118c612d'\r\n secret = 'SEC93212bd880aad638cc0df2b28a72ef4fdf6651cacb8a6a4bc71dcf09705d458d'\r\n\r\n # 生成时间戳\r\n timestamp = str(round(time.time() * 1000))\r\n\r\n # 生成签名\r\n secret_enc = secret.encode('utf-8')\r\n string_to_sign = f'{timestamp}\\n{secret}'\r\n string_to_sign_enc = string_to_sign.encode('utf-8')\r\n hmac_code = hmac.new(secret_enc, string_to_sign_enc, digestmod=hashlib.sha256).digest()\r\n sign = urllib.parse.quote_plus(base64.b64encode(hmac_code))\r\n\r\n # 构建最终的 Webhook URL\r\n params = {\r\n 'access_token': webhook_url.split('=')[1],\r\n 'timestamp': timestamp,\r\n 'sign': sign\r\n }\r\n encoded_params = urllib.parse.urlencode(params)\r\n final_webhook_url = f'https://oapi.dingtalk.com/robot/send?{encoded_params}'\r\n\r\n # 记录最终的 Webhook URL\r\n logging.info(f\"钉钉机器人Webhook URL: {final_webhook_url}\")\r\n\r\n # 构建消息体\r\n headers = {'Content-Type': 'application/json'}\r\n message = {\r\n 'msgtype': 'link',\r\n 'link': {\r\n 'title': title,\r\n 'messageUrl': test_report_url,\r\n 'text': test_report_url\r\n },\r\n \"at\": {\r\n \"atMobiles\": [mobile],\r\n \"isAtAll\": True\r\n }\r\n }\r\n\r\n try:\r\n # 发送 POST 请求\r\n response = requests.post(final_webhook_url, data=json.dumps(message), headers=headers)\r\n\r\n # 检查响应状态码\r\n if response.status_code == 200:\r\n logging.info('消息发送成功!')\r\n logging.info(f'响应内容: {response.text}')\r\n else:\r\n logging.error(f'消息发送失败,状态码: {response.status_code}')\r\n logging.error(f'响应内容: {response.text}')\r\n except requests.exceptions.RequestException as e:\r\n logging.error(f'请求异常: {e}')\r\n\r\n# 调用框架自带生成的测试报告\r\ndef get_latest_report_file(report_dir, base_url):\r\n \"\"\"\r\n 获取指定目录下最新的HTML报告文件,并返回带有基础URL的完整路径。\r\n\r\n :param report_dir: 报告文件所在的目录\r\n :param base_url: 基础URL\r\n :return: 最新的HTML报告文件的完整URL,如果没有找到则返回None\r\n \"\"\"\r\n # 记录调用此函数的日志\r\n logging.info(\"开始调用get_latest_report_file函数获取报告文件\")\r\n\r\n # 确保报告目录存在\r\n if not os.path.exists(report_dir):\r\n logging.error(f\"报告目录 {report_dir} 不存在。\")\r\n return None\r\n\r\n # 获取指定目录下所有符合模式的HTML报告文件\r\n report_files = glob.glob(os.path.join(report_dir, 'report_*.html'))\r\n\r\n # 打印找到的文件列表\r\n logging.debug(f\"找到的报告文件: {report_files}\")\r\n\r\n # 如果没有找到报告文件,记录警告信息并返回None\r\n if not report_files:\r\n logging.warning(\"在指定目录中没有找到报告文件。\")\r\n return None\r\n\r\n # 找到最新修改的报告文件\r\n latest_file = max(report_files, key=os.path.getmtime)\r\n\r\n # 获取最新报告文件的最后修改时间\r\n last_modified_time = datetime.fromtimestamp(os.path.getmtime(latest_file)).strftime('%Y-%m-%d %H:%M:%S')\r\n\r\n # 记录最新报告文件的信息\r\n logging.info(f\"最新报告文件: {latest_file}, 最后修改时间: {last_modified_time}\")\r\n\r\n # 将文件路径转换为相对于基础URL的相对路径\r\n relative_path = os.path.relpath(latest_file, report_dir)\r\n\r\n # 生成完整的URL\r\n full_url = f\"{base_url}/{relative_path}\".replace(\"\\\\\", \"/\")\r\n\r\n # 返回完整的URL\r\n return full_url\r\n\r\n# 定义发送钉钉报告函数\r\ndef get_reportfile_send_dingding(report_title, report_url_prefix, ding_type):\r\n try:\r\n # 获取报告文件所在的目录\r\n report_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..','log')\r\n\r\n # 获取基础URL\r\n base_url = report_url_prefix\r\n\r\n # 获取最新的报告文件\r\n latest_report = get_latest_report_file(report_dir, base_url)\r\n\r\n # 如果找到了最新的报告文件,则发送报告链接到钉钉\r\n if latest_report:\r\n logging.info(f\"最新报告文件URL: {latest_report}\")\r\n\r\n try:\r\n # 记录调用钉钉消息通知函数的日志\r\n logging.info(\"开始调用钉钉消息通知函数\")\r\n\r\n # 调用钉钉发送消息接口进行推送测试报告链接\r\n dingding_send_message(latest_report, report_title, \"13724387318\", ding_type)\r\n\r\n # 记录钉钉消息通知函数调用成功的日志\r\n logging.info(\"钉钉消息通知函数调用成功\")\r\n except Exception as e:\r\n # 记录钉钉消息通知函数调用失败的日志\r\n logging.error(f\"钉钉消息通知函数调用失败: {e}\")\r\n else:\r\n # 记录没有找到报告文件的日志\r\n logging.warning(\"没有找到报告文件以发送。\")\r\n\r\n except subprocess.CalledProcessError as e:\r\n # 处理子进程调用失败的异常\r\n logging.error(f\"命令执行失败,返回码 {e.returncode}: {e.output}\")\r\n except OSError as e:\r\n # 处理操作系统相关的异常\r\n logging.error(f\"发生操作系统错误: {e}\")\r\n finally:\r\n # 无论是否成功,都记录测试结束的日志\r\n logging.info(\"自动化测试完成。\")\r\n\r\n# 获取csv文件数据\r\ndef read_csv_data(csv_file_path):\r\n \"\"\"\r\n 读取CSV文件中的数据,并将其转换为一个包含字典的列表,每个字典代表一行测试用例数据。\r\n 参数:\r\n csv_file_path (str): CSV文件的路径。\r\n 返回:\r\n list: 包含字典的列表,每个字典包含测试用例的名称和参数。\r\n \"\"\"\r\n # 打开CSV文件,使用只读模式,确保兼容性并处理编码\r\n with open(csv_file_path, mode='r', newline='', encoding='utf-8') as file:\r\n # 创建CSV阅读器\r\n reader = csv.reader(file)\r\n # 读取表头,为后续数据解析做准备\r\n headers = next(reader)\r\n ddt_cases = []\r\n # 遍历CSV文件中的每一行数据\r\n for row in reader:\r\n # 将每一行数据转换为字典,其中包含测试用例的名称和参数\r\n case = {\r\n 'name': row[0],\r\n 'para': row[1:]\r\n }\r\n # 将转换后的测试用例数据添加到列表中\r\n ddt_cases.append(case)\r\n # 日志记录:CSV文件已读取\r\n INFO(\"CSV文件已读取\")\r\n # 返回包含所有测试用例数据的列表\r\n return ddt_cases\r\n\r\ndef run_automation_test(report_title, report_url_prefix , ding_type):\r\n \"\"\"\r\n 运行自动化测试并生成报告。\r\n\r\n 参数:\r\n - report_title: 报告的标题\r\n - report_url_prefix: 报告URL的前缀\r\n - test_case: 测试用例脚本执行的标签名\r\n \"\"\"\r\n # 记录测试开始的日志\r\n logging.info(\"开始自动化测试...\")\r\n\r\n # 构建运行测试命令\r\n command = [\r\n 'hytest',\r\n '--report_title', report_title,\r\n '--report_url_prefix', report_url_prefix\r\n ]\r\n\r\n # 记录将要执行的命令日志\r\n logging.info(f\"执行命令: {' '.join(command)}\")\r\n\r\n try:\r\n # 执行测试命令并获取结果\r\n result = subprocess.run(command, capture_output=True, text=True, check=True)\r\n\r\n # 记录命令的标准输出和错误输出\r\n logging.debug(f\"命令标准输出: {result.stdout}\")\r\n logging.debug(f\"命令错误输出: {result.stderr}\")\r\n except subprocess.CalledProcessError as e:\r\n # 处理子进程调用失败的异常\r\n logging.error(f\"命令执行失败,返回码 {e.returncode}: {e.output}\")\r\n except OSError as e:\r\n # 处理操作系统相关的异常\r\n logging.error(f\"发生操作系统错误: {e}\")\r\n finally:\r\n # 无论测试是否成功,都记录测试结束的日志\r\n logging.info(\"自动化测试完成。\")\r\n\r\n # 调用回调函数处理后续操作\r\n get_reportfile_send_dingding(f\"{report_title}\", report_url_prefix, ding_type)\r\n Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/运维集控/项目测试/运维标准版/lib/base.py b/运维集控/项目测试/运维标准版/lib/base.py --- a/运维集控/项目测试/运维标准版/lib/base.py (revision 1114284965c773bf063d20e1486fe7c5aa398274) +++ b/运维集控/项目测试/运维标准版/lib/base.py (date 1741848209044) @@ -1,4 +1,6 @@ +import openpyxl import pandas as pd +import re import csv import urllib import glob @@ -22,7 +24,7 @@ from selenium.webdriver.edge.options import Options from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.support import expected_conditions as EC -from selenium.common import TimeoutException,ElementNotInteractableException +from selenium.common import TimeoutException, ElementNotInteractableException, NoSuchElementException from selenium.webdriver.common.keys import Keys from time import sleep @@ -44,7 +46,7 @@ wd.maximize_window() wd.implicitly_wait(10) -# 定义调整屏幕分辨率,仅内部环境跑定时任务需要使用。 +# 定义调整屏幕分辨率,仅虚拟机电脑环境跑定时任务需要使用。 def change_resolution(width, height): # 获取当前显示器的设备上下文(Device Context, DC) device = win32api.EnumDisplayDevices(None, 0) @@ -135,6 +137,19 @@ except Exception as e: print(f"An error occurred: {e}") +def browser_quit(): + """ + 退出浏览器并释放资源。 + + 该函数从全局存储中获取浏览器驱动实例,并调用其quit方法来关闭浏览器并释放相关资源。 + """ + # 清除浏览器 + INFO("清除浏览器") + # 从全局存储中获取浏览器驱动实例 + wd = GSTORE['wd'] + # 调用浏览器驱动实例的quit方法,关闭浏览器并释放资源 + wd.quit() + # 进入后台管理系统页面 def enter_system(): wd = GSTORE['wd'] @@ -390,6 +405,13 @@ # 记录最终的 Webhook URL logging.info(f"钉钉机器人Webhook URL: {final_webhook_url}") + # 调用测试结果获取函数 + open_browser() + wd = GSTORE['wd'] + # print(latest_report) + test_result = get_test_result(test_report_url, wd) + browser_quit() + # 构建消息体 headers = {'Content-Type': 'application/json'} message = { @@ -397,7 +419,7 @@ 'link': { 'title': title, 'messageUrl': test_report_url, - 'text': test_report_url + 'text': f"通过:{test_result['pass_percent']}" + f"失败:{test_result['fail_percent']}" + f"异常:{test_result['exception_percent']}", }, "at": { "atMobiles": [mobile], @@ -537,6 +559,7 @@ # 返回包含所有测试用例数据的列表 return ddt_cases +# 定义生成的报告,并且发送钉钉通知 def run_automation_test(report_title, report_url_prefix , ding_type): """ 运行自动化测试并生成报告。 @@ -578,3 +601,349 @@ # 调用回调函数处理后续操作 get_reportfile_send_dingding(f"{report_title}", report_url_prefix, ding_type) + +# 获取报告中的通过率、失败率和异常率,用于发送钉钉报告 +def get_test_result(latest_report, wd): + """ + 获取测试结果页面的通过率、失败率和异常率 + + :param latest_report: 测试结果页面的URL + :param wd: WebDriver实例,用于访问和操作网页 + :return: 包含通过率、失败率和异常率的字典 + """ + # 初始化测试结果字典 + test_result = { + "pass_percent": "", + "fail_percent": "", + "exception_percent": "" + } + + # 访问测试结果页面 + wd.get(latest_report) + sleep(5) + + # 点击简略显示 + safe_click((By.XPATH,"//div[@id='display_mode']"), wd) + sleep(5) + + # 定义一个函数来获取和解析百分比 + def get_percentage(selector, wd): + text = elment_get_text(selector, wd) + logging.info(f"获取的文本:{text}") + match = re.search(r'(\d+(\.\d+)?)%', text) + if match: + return match.group(0) + else: + logging.error(f"未找到百分比匹配项,文本内容: {text}") + return "0" + + # 获取通过率 + pass_percent = get_percentage((By.CSS_SELECTOR, "div[class='result_barchart'] div:nth-child(1) span:nth-child(1)"), wd) + test_result["pass_percent"] = pass_percent + + # 获取失败率 + fail_percent = get_percentage( + (By.CSS_SELECTOR, "body > div.main_section > div.result > div > div:nth-child(2) > span"), wd) + test_result["fail_percent"] = fail_percent + + # 获取异常率 + exception_percent = get_percentage( + (By.CSS_SELECTOR, "body > div.main_section > div.result > div > div:nth-child(3) > span"), wd) + test_result["exception_percent"] = exception_percent + # 输出test_result + logging.info(test_result) + print(test_result) + sleep(5) + + # 返回测试结果字典 + return test_result + +# 通用方法-点击元素 +def safe_click(element_locator, wd): + """ + 对其定位器指定的元素执行安全单击。 + 此函数尝试以处理潜在异常的方式单击元素。 + 它等待元素可见并可单击,然后再尝试单击它。 + 如果该元素在20秒内无法点击,或者它不存在, + 或者不可交互,它会捕获相应的异常并记录一条信息性消息。 + 参数: + -element_locator:要单击的元素的定位器,指定为元组。 + -wd:用于查找元素并与之交互的WebDriver实例。 + """ + try: + # Wait up to 20 seconds for the element to be visible + element = WebDriverWait(wd, 60).until(EC.visibility_of_element_located(element_locator)) + # Attempt to click the element + element.click() + except TimeoutException: + # Log a message if the element is not found or not clickable within 20 seconds + INFO(f"TimeoutException: Element {element_locator} not found or not clickable within 20 seconds.") + except NoSuchElementException: + # Log a message if the element is not found + INFO(f"NoSuchElementException: Element {element_locator} not found.") + except ElementNotInteractableException: + # Log a message if the element is not interactable + INFO(f"ElementNotInteractableException: Element {element_locator} is not interactable.") + +# 通用方法-在输入框输入内容 +def safe_send_keys(element_locator, value, wd): + """ + 安全地向网页元素发送键值。 + 该函数尝试在指定时间内找到指定的网页元素,如果找到并且元素可见,将先清除元素内容,然后发送指定的键值。 + 如果在指定时间内未能找到元素或元素不可点击,则捕获相应的异常并打印错误信息。 + 参数: + element_locator (tuple): 用于定位网页元素的策略和定位器的元组,例如(By.ID, 'element_id')。 + value (str): 要发送到元素的键值字符串。 + wd: WebDriver实例,用于与浏览器交互。 + 异常处理: + - TimeoutException: 如果元素在指定时间内未被找到或不可点击。 + - NoSuchElementException: 如果元素不存在。 + - ElementNotInteractableException: 如果元素存在但不可交互。 + """ + try: + # 等待元素在指定时间内可见 + element = WebDriverWait(wd, 60).until(EC.visibility_of_element_located(element_locator)) + element.clear() # 清除元素的当前值 + element.send_keys(value) # 向元素发送指定的键值 + except TimeoutException: + # 如果元素在指定时间内未被找到或不可点击,打印超时异常信息 + INFO(f"TimeoutException: Element {element_locator} not found or not clickable within 20 seconds.") + except NoSuchElementException: + # 如果元素不存在,打印相应异常信息 + INFO(f"NoSuchElementException: Element {element_locator} not found.") + except ElementNotInteractableException: + # 如果元素不可交互,打印相应异常信息 + INFO(f"ElementNotInteractableException: Element {element_locator} is not interactable.") + +# 通用方法-输入框清除 +def input_clear(element_locator, wd): + """ + 清空输入框中的文本。 + + 该函数通过元素定位器找到指定的输入框,并尝试清空其内容。它使用显式等待来确保元素在尝试清除之前是可见的。 + + 参数: + - element_locator: 用于定位输入框的元素定位器,通常是一个元组,包含定位方法和定位表达式。 + - wd: WebDriver实例,用于与浏览器交互。 + + 异常处理: + - TimeoutException: 如果在指定时间内元素不可见,则捕获此异常并打印超时异常消息。 + - NoSuchElementException: 如果找不到指定的元素,则捕获此异常并打印未找到元素的消息。 + - ElementNotInteractableException: 如果元素不可操作(例如,元素不可见或不可点击),则捕获此异常并打印相应消息。 + """ + try: + # 等待元素可见,并在可见后清空输入框。 + input_element = WebDriverWait(wd, 60).until(EC.visibility_of_element_located(element_locator)) + input_element.clear() + except TimeoutException: + # 如果元素在20秒内不可见,打印超时异常消息。 + print(f"TimeoutException: Element {element_locator} not found or not clickable within 20 seconds.") + except NoSuchElementException: + # 如果找不到元素,打印未找到元素的消息。 + print(f"NoSuchElementException: Element {element_locator} not found.") + except ElementNotInteractableException: + # 如果元素不可操作,打印元素不可操作的消息。 + print(f"ElementNotInteractableException: Element {element_locator} is not interactable.") + +# 通用方法-回车 +def send_keyboard(element_locator, wd): + """ + 向指定元素发送键盘事件。 + + 该函数尝试找到页面上的一个元素,并向其发送RETURN键点击事件。它使用显式等待来确保元素在尝试交互之前是可见的。 + 如果在指定时间内元素不可见、不存在或不可交互,则捕获相应的异常并打印错误消息。 + + 参数: + - element_locator: 用于定位元素的元组,格式为(by, value)。例如,(By.ID, 'element_id')。 + - wd: WebDriver实例,用于与浏览器进行交互。 + + 异常处理: + - TimeoutException: 如果元素在20秒内不可见,则捕获此异常并打印超时错误消息。 + - NoSuchElementException: 如果找不到指定的元素,则捕获此异常并打印未找到元素的错误消息。 + - ElementNotInteractableException: 如果元素不可交互(例如,被遮挡或不可点击),则捕获此异常并打印相应错误消息。 + """ + try: + # 等待元素可见,并在可见后向其发送RETURN键点击事件。 + element = WebDriverWait(wd, 60).until(EC.visibility_of_element_located(element_locator)) + element.send_keys(Keys.RETURN) + except TimeoutException: + # 如果元素在指定时间内不可见,打印超时错误消息。 + print(f"TimeoutException: Element {element_locator} not found or not clickable within 20 seconds.") + except NoSuchElementException: + # 如果找不到指定的元素,打印未找到元素的错误消息。 + print(f"NoSuchElementException: Element {element_locator} not found.") + except ElementNotInteractableException: + # 如果元素不可交互,打印不可交互错误消息。 + print(f"ElementNotInteractableException: Element {element_locator} is not interactable.") + +# 通用方法-获取提示文本 +def get_notify_text(wd,element_locator): + """ + 获取通知文本信息。 + + 该函数通过WebDriver等待特定的元素出现,并截取其文本内容作为通知信息。此外,它还负责在获取通知文本后进行屏幕截图, + 以便于后续的调试或记录需要。 + + 参数: + wd (WebDriver): 由上层传入的WebDriver对象,用于操作浏览器。 + + 返回: + str: 提取的通知文本信息。如果未能提取到信息或发生异常,则返回None。 + """ + try: + # 获取提示信息 + notify_text = WebDriverWait(wd, 60).until( + EC.presence_of_element_located(element_locator) + ).text + # 屏幕截图 + SELENIUM_LOG_SCREEN(wd,"50%") + return notify_text + except Exception as e: + # 记录异常信息 + INFO(f"Exception occurred: {e}") + +# 通用方法-获取页面中的文本内容 +def elment_get_text(element_locator, wd): + """ + 获取页面元素的文本。 + + 该函数通过显式等待的方式,确保页面元素在20秒内可见并获取其文本。 + 如果在规定时间内元素不可见、不存在或不可交互,则会捕获相应的异常并打印错误信息。 + + 参数: + - element_locator: 用于定位页面元素的元组,通常包含定位方式和定位值。 + - wd: WebDriver对象,用于与浏览器进行交互。 + + 返回: + - element_text: 页面元素的文本。如果发生异常,则返回None。 + """ + try: + # 使用WebDriverWait等待页面元素在20秒内可见,并获取其文本。 + element_text = WebDriverWait(wd, 60).until(EC.visibility_of_element_located(element_locator)).text + return element_text + except TimeoutException: + # 如果超过20秒元素仍未可见,则捕获TimeoutException异常并打印错误信息。 + print(f"TimeoutException: Element {element_locator} not found or not clickable within 20 seconds.") + except NoSuchElementException: + # 如果页面上不存在该元素,则捕获NoSuchElementException异常并打印错误信息。 + print(f"NoSuchElementException: Element {element_locator} not found.") + except ElementNotInteractableException: + # 如果元素存在但不可交互(例如被遮挡),则捕获ElementNotInteractableException异常并打印错误信息。 + print(f"ElementNotInteractableException: Element {element_locator} is not interactable.") + +# 通用方法-读取XLSX文件中的数据,并将其转换为一个包含字典的列表 +def read_xlsx_data(xlsx_file_path): + """ + 读取XLSX文件中的数据,并将其转换为一个包含字典的列表,每个字典代表一行测试用例数据。 + + 参数: + xlsx_file_path (str): XLSX文件的路径。 + + 返回: + list: 包含字典的列表,每个字典包含测试用例的名称和参数。 + """ + # 打开XLSX文件 + workbook = openpyxl.load_workbook(xlsx_file_path) + # 假设数据在第一个工作表中 + sheet = workbook.active + + # 读取表头,从第三行开始 + headers = [cell.value for cell in sheet[3]] + + # 打印表头列名 + # print(f"表头列名: {headers}") + + # 找到表头中名为 'JSON' 的列索引 + try: + json_index = headers.index('JSON') + except ValueError as e: + raise ValueError(f"表头中没有找到所需的列: {e}") + + ddt_cases = [] + # 遍历XLSX文件中的每一行数据,从第四行开始 + for row in sheet.iter_rows(min_row=4, values_only=True): + # 获取 JSON 列的数据 + json_data = row[json_index] + + # 打印 JSON 数据以进行调试 + # print(f"JSON 数据: {json_data}") + + # 解析 JSON 字符串 + try: + if json_data: + parsed_json = json.loads(json_data) + else: + raise ValueError("JSON 数据为空") + except json.JSONDecodeError: + raise ValueError(f"无法解析 JSON 数据: {json_data}") + + # 将解析后的 JSON 数据添加到列表中 + ddt_cases.append(parsed_json) + + # 日志记录:XLSX文件已读取 + INFO("XLSX文件已读取") + # 返回包含所有测试用例数据的列表 + return ddt_cases + +# 通用方法-转换字符串类型 +def get_by_enum(type_str): + """ + 将字符串类型的定位器类型转换为 selenium.webdriver.common.by.By 枚举类型。 + + 参数: + type_str (str): 定位器类型字符串,例如 'XPATH'。 + + 返回: + selenium.webdriver.common.by.By: 对应的 By 枚举类型。 + """ + type_str = type_str.upper() + if type_str == 'XPATH': + return By.XPATH + elif type_str == 'ID': + return By.ID + elif type_str == 'NAME': + return By.NAME + elif type_str == 'CLASS_NAME': + return By.CLASS_NAME + elif type_str == 'CSS_SELECTOR': + return By.CSS_SELECTOR + elif type_str == 'TAG_NAME': + return By.TAG_NAME + elif type_str == 'LINK_TEXT': + return By.LINK_TEXT + elif type_str == 'PARTIAL_LINK_TEXT': + return By.PARTIAL_LINK_TEXT + else: + raise ValueError(f"未知的定位器类型: {type_str}") + +# 通用方法-用户登录 +def user_login(element_locators, username, password, verifycode): + """ + 管理员登录函数。 + 该函数通过模拟用户输入用户名、密码和验证码,并点击登录按钮,以实现管理员登录。 + """ + # 获取webdriver实例 + wd = GSTORE['wd'] + + # 打印用户名输入信息 + INFO(f"输入用户名:{username}") + # 向用户名输入框发送用户名 + safe_send_keys(element_locators['username_locator'], f'{username}', wd) + sleep(5) + + # 打印密码输入信息 + INFO(f"输入密码:{password}") + # 向密码输入框发送密码 + safe_send_keys(element_locators['password_locator'], f"{password}", wd) + sleep(5) + + # 打印验证码输入信息 + INFO(f"输入验证码:{verifycode}") + # 向验证码输入验证码 + safe_send_keys(element_locators['verifycode_locator'], f"{verifycode}", wd) + sleep(5) + + #点击登录按钮 + INFO("点击登录按钮") + safe_click(element_locators['submitButton_locator'], wd) + sleep(5) Index: 运维集控/项目测试/运维标准版/testdata/08设备管理/新增设备.csv IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/运维集控/项目测试/运维标准版/testdata/08设备管理/新增设备.csv b/运维集控/项目测试/运维标准版/testdata/08设备管理/新增设备.csv --- a/运维集控/项目测试/运维标准版/testdata/08设备管理/新增设备.csv (revision 1114284965c773bf063d20e1486fe7c5aa398274) +++ b/运维集控/项目测试/运维标准版/testdata/08设备管理/新增设备.csv (date 1741834618398) @@ -1,0 +1,2 @@ +name,area_name,device_name,type,brand,model,sn,ip,tag,supplier,contact,price,expiry_time,sort,useYear,description,relateMaster,outMaster +新增设备-001-正常新增设备,测试区域11,测试设备0,智慧屏设备,华为品牌,Ideahub,123456789,192.168.1.1,资产设备1,华为,13141234567,2000,2025-01-01 12:00:00,1,3,用途说明1,否,否 \ No newline at end of file Index: 运维集控/项目测试/运维标准版/定时任务执行.py IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.BaseRevisionTextPatchEP <+>import schedule\r\nimport threading\r\nimport queue\r\nfrom lib.base import *\r\nimport time\r\nimport logging\r\n\r\n# 配置日志记录器,仅输出到控制台\r\nlogging.basicConfig(\r\n level=logging.DEBUG, # 设置日志级别为 DEBUG\r\n format='%(asctime)s - %(levelname)s - %(message)s', # 日志格式:时间 - 日志级别 - 消息\r\n handlers=[\r\n logging.StreamHandler() # 将日志输出到控制台\r\n ]\r\n)\r\n\r\n\"\"\"\r\n 执行指令:\r\n 1.打开一个终端输入:\r\n - cd .\\运维集控\\项目测试\\运维标准版\\\r\n - python -m http.server 80 --directory log\r\n 2.打开新终端输入:\r\n - cd .\\运维集控\\项目测试\\运维标准版\\ngrok\\\r\n - .\\start.bat\r\n 2.再打开一个终端输入:\r\n - cd .\\运维集控\\项目测试\\运维标准版\\\r\n - python .\\定时任务执行.py\r\n\"\"\"\r\n\r\n# 创建一个任务队列,用于存储待处理的任务\r\ntask_queue = queue.Queue()\r\n\r\ndef run_task(task, *args, **kwargs):\r\n # 将任务及其参数放入任务队列\r\n task_queue.put((task, args, kwargs))\r\n logging.debug(f\"任务已加入队列: {task.__name__} with args: {args} and kwargs: {kwargs}\")\r\n\r\ndef worker():\r\n # 工作线程的主循环\r\n while True:\r\n # 从任务队列中获取任务及其参数\r\n task, args, kwargs = task_queue.get()\r\n try:\r\n # 记录任务开始执行的时间\r\n logging.debug(f\"开始执行任务: {task.__name__} with args: {args} and kwargs: {kwargs}\")\r\n # 执行任务并获取结果\r\n result = task(*args, **kwargs)\r\n # 如果任务有返回结果,记录日志\r\n if result:\r\n logging.info(result)\r\n except Exception as e:\r\n # 捕获任务执行过程中发生的任何异常并记录错误日志\r\n logging.error(f\"执行任务时发生错误: {e}\", exc_info=True)\r\n finally:\r\n # 无论任务是否成功执行,都标记任务已完成\r\n task_queue.task_done()\r\n # 记录任务完成的时间\r\n logging.debug(f\"任务完成: {task.__name__}\")\r\n\r\ndef start_workers(num_workers):\r\n # 启动指定数量的工作线程\r\n for _ in range(num_workers):\r\n # 创建一个新的工作线程,目标函数为 worker,设置为守护线程\r\n threading.Thread(target=worker, daemon=True).start()\r\n\r\n# 启动3个工作线程\r\nstart_workers(3)\r\n\r\n# 定义每天定时执行的任务\r\n# 每天早上07:50执行后台系统设置功能测试\r\nfor day in ['monday', 'tuesday', 'wednesday', 'thursday', 'friday']:\r\n schedule.every().__getattribute__(day).at(\"07:50\").do(run_task, run_automation_test, report_title=\"运维系统测试报告\", report_url_prefix=\"http://nat.ubainsyun.com:31135\", ding_type=\"标准版巡检\")\r\n\r\n# 调试使用\r\n#schedule.every().day.at(\"09:59\").do(run_task, run_automation_test, report_title=\"运维系统脚本调试\", report_url_prefix=\"http://nat.ubainsyun.com:31135\", ding_type=\"标准版巡检\")\r\n\r\ntry:\r\n # 无限循环,持续检查并执行计划任务\r\n while True:\r\n schedule.run_pending() # 检查并执行所有待处理的任务\r\n time.sleep(1) # 每秒检查一次\r\nexcept KeyboardInterrupt:\r\n # 捕获用户中断信号 (Ctrl+C)\r\n logging.info(\"Scheduler interrupted by user.\")\r\nexcept Exception as e:\r\n # 捕获其他未预期的异常\r\n logging.error(f\"Unexpected error: {e}\", exc_info=True) Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/运维集控/项目测试/运维标准版/定时任务执行.py b/运维集控/项目测试/运维标准版/定时任务执行.py --- a/运维集控/项目测试/运维标准版/定时任务执行.py (revision 1114284965c773bf063d20e1486fe7c5aa398274) +++ b/运维集控/项目测试/运维标准版/定时任务执行.py (date 1741836024783) @@ -69,7 +69,7 @@ # 定义每天定时执行的任务 # 每天早上07:50执行后台系统设置功能测试 for day in ['monday', 'tuesday', 'wednesday', 'thursday', 'friday']: - schedule.every().__getattribute__(day).at("07:50").do(run_task, run_automation_test, report_title="运维系统测试报告", report_url_prefix="http://nat.ubainsyun.com:31135", ding_type="标准版巡检") + schedule.every().__getattribute__(day).at("11:21").do(run_task, run_automation_test, report_title="运维系统测试报告", report_url_prefix="http://nat.ubainsyun.com:31135", ding_type="标准版巡检") # 调试使用 #schedule.every().day.at("09:59").do(run_task, run_automation_test, report_title="运维系统脚本调试", report_url_prefix="http://nat.ubainsyun.com:31135", ding_type="标准版巡检") Index: 统一平台/base/bases.py IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/统一平台/base/bases.py b/统一平台/base/bases.py new file mode 100644 --- /dev/null (date 1742452424094) +++ b/统一平台/base/bases.py (date 1742452424094) @@ -0,0 +1,1605 @@ +import csv +import glob +import re +import urllib +from selenium.webdriver.chrome.service import Service +import json +import hmac +import hashlib +import base64 +import psutil +import time +import subprocess +import logging +from hytest import * +from selenium import webdriver +from selenium.common import ElementNotInteractableException +from selenium.webdriver.common.keys import Keys +from urllib.parse import urlencode +from datetime import datetime +from selenium.webdriver.chrome.service import Service as ChromeService +from webdriver_manager.chrome import ChromeDriverManager + +# 获取当前脚本的绝对路径 +current_dir = os.path.dirname(os.path.abspath(__file__)) +# 获取当前脚本的父目录 +parent_dir = os.path.dirname(current_dir) +logging.info(parent_dir) +# 添加路径 +sys.path.append(current_dir) + +# 配置日志记录器,仅输出到控制台 +logging.basicConfig( + level=logging.DEBUG, + format='%(asctime)s - %(levelname)s - %(message)s', + handlers=[ + logging.StreamHandler() + ] +) + +# 浏览器初始化函数 +def browser_init(login_type): + """ + 初始化浏览器设置和实例。 + + 此函数旨在创建并配置一个Chrome浏览器实例,包括设置Chrome选项以排除不必要的日志, + 并尝试打开特定的登录页面。任何初始化过程中出现的错误都会被捕获并记录。 + + 参数: + login_type (str): 指定登录类型,根据不同的登录类型选择不同的URL。 + + 返回: + 无 + """ + # 标记初始化过程的开始 + INFO("'----------' 正在初始化浏览器 '----------'") + + # 创建Chrome选项实例,用于配置浏览器行为 + options = webdriver.ChromeOptions() + # 添加实验性选项,排除某些命令行开关以减少输出日志 + options.add_experimental_option('excludeSwitches', ['enable-Logging']) + # 忽略证书错误,允许在本地主机上运行时不安全 + options.add_argument('--ignore-certificate-errors') + # 禁用自动化控制特征检测,避免被网站识别为自动化流量 + options.add_argument('--disable-blink-features=AutomationControlled') + # 允许不安全的本地主机运行,通常用于开发和测试环境 + options.add_argument('--allow-insecure-localhost') + + # 使用webdriver_manager自动下载并管理chromedriver + driver_path = ChromeDriverManager().install() + service = ChromeService(driver_path) + # 手动指定ChromeDriver的路径 + # service = Service(r'C:\Users\29194\AppData\Local\Programs\Python\Python310\Scripts\chromedriver.exe') + try: + # 创建WebDriver实例 + wd = webdriver.Chrome(service=service, options=options) + # 设置隐式等待时间为10秒,以允许元素加载 + wd.implicitly_wait(10) + + # 获取登录URL + login_url = get_login_url_from_config(login_type) + # 打开对应类型的登录页面 + wd.get(login_url) + # 最大化浏览器窗口 + wd.maximize_window() + + # 将WebDriver实例存储在全局存储器中,以便后续使用 + GSTORE['wd'] = wd + # 标记初始化过程完成 + INFO("'----------' 浏览器初始化完成 '----------'") + except Exception as e: + # 捕获并记录初始化过程中的任何异常 + logging.error(f"浏览器初始化失败:{e}") + +# 从配置项config中获取登录URL +def get_login_url_from_config(login_type): + """ + 从配置文件中读取登录URL。 + + 参数: + login_type (str): 指定登录类型,根据不同的登录类型选择不同的URL。 + + 返回: + str: 对应的登录URL。 + """ + # 检查 login_type 是否为空或 None + if not login_type: + raise ValueError("login_type 不能为空") + + # 获取当前脚本的绝对路径 + current_dir = os.path.dirname(os.path.abspath(__file__)) + # 构建配置文件的绝对路径,指向 ubains-module-test 目录下的 config.json + config_path = os.path.abspath(os.path.join(current_dir, '..', 'config', 'config.json')) + # 规范化路径,防止路径遍历攻击 + config_path = os.path.normpath(config_path) + + # 记录配置文件路径以便调试,对路径进行脱敏处理 + logging.info(f"配置文件路径: {os.path.basename(config_path)}") + + # 检查文件是否存在 + if not os.path.exists(config_path): + # 如果配置文件不存在,则抛出异常 + raise FileNotFoundError(f"配置文件 {config_path} 不存在") + + try: + # 读取配置文件 + with open(config_path, 'r', encoding='utf-8') as config_file: + # 将配置文件内容解析为 JSON 格式 + config = json.load(config_file) + # 根据 login_type 获取对应的登录 URL + login_url = config.get(login_type) + # 记录正在打开的登录页面类型和 URL + logging.info(f"正在打开 {login_type} 的登录页面:{login_url}") + except IOError as e: + # 处理文件读取异常 + raise IOError(f"读取配置文件失败: {e}") + except json.JSONDecodeError as e: + # 处理 JSON 解析异常 + raise json.JSONDecodeError(f"解析配置文件失败: {e}") + + # 检查是否成功获取到 URL + if not login_url: + # 如果未找到对应的 URL,则抛出异常 + raise ValueError(f"未找到对应的 URL 配置项: {login_type}") + + # 返回登录 URL + return login_url + +# 管理员登录函数 +def admin_login(username, password): + """ + 管理员登录函数。 + 该函数通过模拟用户输入用户名、密码和验证码,并点击登录按钮,以实现管理员登录。 + """ + # 获取webdriver实例 + wd = GSTORE['wd'] + + # 打印用户名输入信息 + INFO(f"输入用户名:{username}") + # 向用户名输入框发送用户名 + safe_send_keys((By.XPATH, "//input[@placeholder='请输入账号或手机号或邮箱号']"), f'{username}', wd) + + # 打印密码输入信息 + INFO(f"输入密码:{password}") + # 向密码输入框发送密码 + safe_send_keys((By.XPATH, "//input[@placeholder='请输入密码']"), f"{password}", wd) + + # 打印验证码输入信息 + INFO("输入验证码:csba") + # 向验证码输入框发送验证码 + safe_send_keys((By.XPATH, "//input[@placeholder='请输入图形验证码']"), "csba", wd) + # 隐式等待5秒,以确保验证码被正确处理 + wd.implicitly_wait(5) + + # 打印登录按钮点击信息 + INFO("点击登录按钮") + # 点击登录按钮 + safe_click((By.XPATH, "//input[@value='登 录']"), wd) + +# 进入预定后台函数 +def enter_the_backend(): + """ + 进入后台系统界面。 + 该函数通过模拟点击操作,找到并点击后台系统入口,以进入后台界面。 + """ + # 记录进入后台系统的操作信息 + INFO("进入后台") + + # 获取webdriver对象,用于后续的页面元素操作 + wd = GSTORE['wd'] + + # 执行点击操作,通过XPath定位到后台系统入口图标并点击 + safe_click((By.XPATH, "//img[@title='后台系统']"), wd) + +# 输入框输入值函数 +def safe_send_keys(element_locator, value, wd): + """ + 安全地向网页元素发送键值。 + 该函数尝试在指定时间内找到指定的网页元素,如果找到并且元素可见,将先清除元素内容,然后发送指定的键值。 + 如果在指定时间内未能找到元素或元素不可点击,则捕获相应的异常并打印错误信息。 + 参数: + element_locator (tuple): 用于定位网页元素的策略和定位器的元组,例如(By.ID, 'element_id')。 + value (str): 要发送到元素的键值字符串。 + wd: WebDriver实例,用于与浏览器交互。 + 异常处理: + - TimeoutException: 如果元素在指定时间内未被找到或不可点击。 + - NoSuchElementException: 如果元素不存在。 + - ElementNotInteractableException: 如果元素存在但不可交互。 + """ + try: + # 等待元素在指定时间内可见 + element = WebDriverWait(wd, 5).until(EC.visibility_of_element_located(element_locator)) + element.clear() # 清除元素的当前值 + element.send_keys(value) # 向元素发送指定的键值 + except TimeoutException: + # 如果元素在指定时间内未被找到或不可点击,打印超时异常信息 + INFO(f"超时异常:元素 {element_locator} 在20秒内未找到或无法点击。") + except NoSuchElementException: + # 如果元素不存在,打印相应异常信息 + INFO(f"找不到元素:元素 {element_locator} 不存在。") + except ElementNotInteractableException: + # 如果元素不可交互,打印相应异常信息 + INFO(f"元素不可交互:元素 {element_locator} 当前状态无法操作。") + + +# 点击按钮函数 +def safe_click(element_locator, wd): + """ + 对其定位器指定的元素执行安全单击。 + 此函数尝试以处理潜在异常的方式单击元素。 + 它等待元素可见并可单击,然后再尝试单击它。 + 如果该元素在20秒内无法点击,或者它不存在, + 或者不可交互,它会捕获相应的异常并记录一条信息性消息。 + 参数: + -element_locator:要单击的元素的定位器,指定为元组。 + -wd:用于查找元素并与之交互的WebDriver实例。 + """ + try: + # Wait up to 20 seconds for the element to be visible + element = WebDriverWait(wd, 5).until(EC.visibility_of_element_located(element_locator)) + # Attempt to click the element + element.click() + except TimeoutException: + # 如果元素在20秒内未找到或不可点击,记录日志 + INFO(f"超时异常:在20秒内未找到或无法点击元素 {element_locator}。") + except NoSuchElementException: + # 如果找不到指定的元素,记录日志 + INFO(f"找不到元素:元素 {element_locator} 不存在。") + except ElementNotInteractableException: + # 如果元素不可操作,记录日志 + INFO(f"元素不可操作:元素 {element_locator} 当前无法交互。") + + +from time import sleep +from selenium.webdriver.common.by import By + +# 议题输入和上传议题文件函数 +def issue_send_and_upload(wd, issue_num, issue_name): + """ + 输入议题名称以及上传议题文件。 + + 参数: + wd: WebDriver实例,用于操作浏览器。 + issue_num: 需要上传的议题文件数量。 + issue_name: 会议议题的名称。 + """ + + # 议题文件的路径列表 + issue_file_path = [ + r"D:\GithubData\自动化\ubains-module-test\预定系统\reports\issue_file\5.164Scan 安全报告.pdf", + r"D:\GithubData\自动化\ubains-module-test\预定系统\reports\issue_file\IdeaTop软件配置&操作说明文档.docx", + r"D:\GithubData\自动化\ubains-module-test\预定系统\reports\issue_file\ideaTop部署配置视频.mp4", + r"D:\GithubData\自动化\ubains-module-test\预定系统\reports\issue_file\IdeaTop软件配置&操作说明文档.docx", + r"D:\GithubData\自动化\ubains-module-test\预定系统\reports\issue_file\议题图片.png" + ] + + # 打印并输入议题名称 + INFO(f"输入议题名称:{issue_name}") + safe_send_keys((By.XPATH, f"(//input[@placeholder='请输入会议议题'])[1]"), f"{issue_name}", wd) + + # 点击【上传文件】按钮以开始上传议题文件 + INFO("点击【上传文件】按钮") + safe_click((By.XPATH, f"(//div[@class='topicsHandleButton uploadFile'][contains(text(),'上传文件(0)')])[1]"), wd) + sleep(2) + + # 遍历每个议题文件进行上传 + for i in range(issue_num): + # 检查文件是否存在 + if not os.path.exists(issue_file_path[i]): + INFO(f"文件 {issue_file_path[i]} 不存在,跳出函数") + return + + # 定位【选择文件】按钮 + upload_button = wd.find_element(By.XPATH, '//*[@id="global-uploader-btn"]/input') + sleep(2) + + # 选择议题文件上传 + upload_button.send_keys(issue_file_path[i]) + # 等待文件上传完成 + sleep(15) + + # 截取上传完成后的屏幕日志 + SELENIUM_LOG_SCREEN(wd, "50%", "Exhibit_Inspect", "Meeting_Message", "添加议题文件") + + # 点击【确定】按钮完成上传 + safe_click((By.XPATH, + "//div[@aria-label='会议文件上传']//div[@class='el-dialog__footer']//div//span[contains(text(),'确定')]"), + wd) + sleep(2) + +# 清除输入框函数 +def input_clear(element_locator, wd): + """ + 清空输入框中的文本。 + + 该函数通过元素定位器找到指定的输入框,并尝试清空其内容。它使用显式等待来确保元素在尝试清除之前是可见的。 + + 参数: + - element_locator: 用于定位输入框的元素定位器,通常是一个元组,包含定位方法和定位表达式。 + - wd: WebDriver实例,用于与浏览器交互。 + + 异常处理: + - TimeoutException: 如果在指定时间内元素不可见,则捕获此异常并打印超时异常消息。 + - NoSuchElementException: 如果找不到指定的元素,则捕获此异常并打印未找到元素的消息。 + - ElementNotInteractableException: 如果元素不可操作(例如,元素不可见或不可点击),则捕获此异常并打印相应消息。 + """ + try: + # 等待元素可见,并在可见后清空输入框。 + input_element = WebDriverWait(wd, 5).until(EC.visibility_of_element_located(element_locator)) + input_element.clear() + except TimeoutException: + # 如果元素在20秒内未找到或不可点击,记录日志 + INFO(f"超时异常:在20秒内未找到或无法点击元素 {element_locator}。") + except NoSuchElementException: + # 如果找不到指定的元素,记录日志 + INFO(f"找不到元素:元素 {element_locator} 不存在。") + except ElementNotInteractableException: + # 如果元素不可操作,记录日志 + INFO(f"元素不可操作:元素 {element_locator} 当前无法交互。") + +# 键盘输入函数,例如【回车】键等操作 +def send_keyboard(element_locator, wd): + """ + 向指定元素发送键盘事件。 + + 该函数尝试找到页面上的一个元素,并向其发送RETURN键点击事件。它使用显式等待来确保元素在尝试交互之前是可见的。 + 如果在指定时间内元素不可见、不存在或不可交互,则捕获相应的异常并打印错误消息。 + + 参数: + - element_locator: 用于定位元素的元组,格式为(by, value)。例如,(By.ID, 'element_id')。 + - wd: WebDriver实例,用于与浏览器进行交互。 + + 异常处理: + - TimeoutException: 如果元素在20秒内不可见,则捕获此异常并打印超时错误消息。 + - NoSuchElementException: 如果找不到指定的元素,则捕获此异常并打印未找到元素的错误消息。 + - ElementNotInteractableException: 如果元素不可交互(例如,被遮挡或不可点击),则捕获此异常并打印相应错误消息。 + """ + try: + # 等待元素可见,并在可见后向其发送RETURN键点击事件。 + element = WebDriverWait(wd, 5).until(EC.visibility_of_element_located(element_locator)) + element.send_keys(Keys.RETURN) + except TimeoutException: + # 如果元素在指定时间内不可见,打印超时错误消息。 + print(f"TimeoutException: Element {element_locator} not found or not clickable within 20 seconds.") + except NoSuchElementException: + # 如果找不到指定的元素,打印未找到元素的错误消息。 + print(f"NoSuchElementException: Element {element_locator} not found.") + except ElementNotInteractableException: + # 如果元素不可交互,打印不可交互错误消息。 + print(f"ElementNotInteractableException: Element {element_locator} is not interactable.") + +# 获取常规提示文本函数,会同步进行截屏操作 +def get_notify_text(wd,element_locator,module_name = None,function_name = None,file_name = None): + """ + 获取通知文本信息。 + + 该函数通过WebDriver等待特定的元素出现,并截取其文本内容作为通知信息。此外,它还负责在获取通知文本后进行屏幕截图, + 以便于后续的调试或记录需要。 + + 参数: + wd (WebDriver): 由上层传入的WebDriver对象,用于操作浏览器。 + element_locator: 用于定位元素的定位器。 + module_name: 模块名称,用于日志记录。 + function_name: 函数名称,用于日志记录。 + file_name: 屏幕截图的名称,用于日志记录。 + + 返回: + str: 提取的通知文本信息。如果未能提取到信息或发生异常,则返回None。 + """ + try: + # 使用WebDriverWait等待元素出现,并获取其文本内容 + notify_text = WebDriverWait(wd, 5).until( + EC.presence_of_element_located(element_locator) + ).text + if module_name or function_name or file_name: + # 如果 module_name, function_name, 或 file_name 有值,则使用这些参数进行屏幕截图 + SELENIUM_LOG_SCREEN(wd, "50%", module_name, function_name, file_name) + else: + # 如果 module_name, function_name, 和 file_name 都没有值,则仅使用 wd 和 "50%" 进行屏幕截图 + SELENIUM_LOG_SCREEN(wd, "50%") + return notify_text + except Exception as e: + # 当发生异常时,记录异常信息 + INFO(f"Exception occurred: {e}") + +# 获取列表的查询结果文本函数 +def elment_get_text(element_locator, wd): + """ + 获取页面元素的文本。 + + 该函数通过显式等待的方式,确保页面元素在20秒内可见并获取其文本。 + 如果在规定时间内元素不可见、不存在或不可交互,则会捕获相应的异常并打印错误信息。 + + 参数: + - element_locator: 用于定位页面元素的元组,通常包含定位方式和定位值。 + - wd: WebDriver对象,用于与浏览器进行交互。 + + 返回: + - element_text: 页面元素的文本。如果发生异常,则返回None。 + """ + try: + # 使用WebDriverWait等待页面元素在20秒内可见,并获取其文本。 + element_text = WebDriverWait(wd, 5).until(EC.visibility_of_element_located(element_locator)).text + return element_text + except TimeoutException: + # 如果超过20秒元素仍未可见,则捕获TimeoutException异常并打印错误信息。 + print(f"TimeoutException: Element {element_locator} not found or not clickable within 20 seconds.") + except NoSuchElementException: + # 如果页面上不存在该元素,则捕获NoSuchElementException异常并打印错误信息。 + print(f"NoSuchElementException: Element {element_locator} not found.") + except ElementNotInteractableException: + # 如果元素存在但不可交互(例如被遮挡),则捕获ElementNotInteractableException异常并打印错误信息。 + print(f"ElementNotInteractableException: Element {element_locator} is not interactable.") + +# 读取csv文件进行数据驱动函数 +def read_csv_data(csv_file_path): + """ + 读取CSV文件中的数据,并将其转换为一个包含字典的列表,每个字典代表一行测试用例数据。 + + 参数: + csv_file_path (str): CSV文件的路径。 + + 返回: + list: 包含字典的列表,每个字典包含测试用例的名称和参数。 + """ + # 打开CSV文件,使用只读模式,确保兼容性并处理编码 + with open(csv_file_path, mode='r', newline='', encoding='utf-8') as file: + # 创建CSV阅读器 + reader = csv.reader(file) + # 读取表头,为后续数据解析做准备 + headers = next(reader) + ddt_cases = [] + # 遍历CSV文件中的每一行数据 + for row in reader: + # 将每一行数据转换为字典,其中包含测试用例的名称和参数 + case = { + 'name': row[0], + 'para': row[1:] + } + # 将转换后的测试用例数据添加到列表中 + ddt_cases.append(case) + # 日志记录:CSV文件已读取 + INFO("CSV文件已读取") + # 返回包含所有测试用例数据的列表 + return ddt_cases + +# 读取测试用例xlsx文件中的JSON数据进行数据驱动函数 +import openpyxl +def read_xlsx_data(xlsx_file_path, sheet_name=None): + """ + 读取XLSX文件中的数据,并将其转换为一个包含字典的列表,每个字典代表一行测试用例数据。 + + 参数: + xlsx_file_path (str): XLSX文件的路径。 + sheet_name (str, optional): 工作表的名称。如果未指定,则使用活动工作表。 + + 返回: + list: 包含字典的列表,每个字典包含测试用例的名称和参数。 + """ + try: + # 打开XLSX文件 + workbook = openpyxl.load_workbook(xlsx_file_path) + except FileNotFoundError: + raise FileNotFoundError(f"文件未找到: {xlsx_file_path}") + except Exception as e: + raise Exception(f"无法打开文件: {e}") + + # 选择工作表 + if sheet_name: + try: + sheet = workbook[sheet_name] + except KeyError: + raise KeyError(f"工作表未找到: {sheet_name}") + else: + sheet = workbook.active + + # 读取表头,从第三行开始 + headers = [cell.value for cell in sheet[3]] + + # 打印表头列名 + # INFO(f"表头列名: {headers}") + + # 找到表头中名为 'JSON' 的列索引 + try: + json_index = headers.index('JSON') + except ValueError as e: + raise ValueError(f"表头中没有找到所需的列: {e}") + + ddt_cases = [] + # 遍历XLSX文件中的每一行数据,从第四行开始 + for row_num, row in enumerate(sheet.iter_rows(min_row=4, values_only=True), start=4): + # 获取 JSON 列的数据 + json_data = row[json_index] + + # 打印 JSON 数据以进行调试 + # INFO(f"行 {row_num} 的 JSON 数据: {json_data}") + + # 检查 JSON 数据是否为空 + if json_data is None or json_data.strip() == "": + # INFO(f"跳过行 {row_num},JSON 数据为空") + continue + + # 解析 JSON 字符串 + try: + parsed_json = json.loads(json_data) + except json.JSONDecodeError: + raise ValueError(f"行 {row_num} 的 JSON 数据无法解析: {json_data}") + + # 将解析后的 JSON 数据添加到列表中 + ddt_cases.append(parsed_json) + + # 日志记录:XLSX文件已读取 + INFO("XLSX文件已读取") + # 返回包含所有测试用例数据的列表 + return ddt_cases + +# 获取当前进程的 CPU 占用率函数 +def get_cpu_usage(interval=1): + """ + 获取当前进程的 CPU 占用率。 + :param interval: 计算 CPU 使用率的时间间隔(秒) + :return: 当前进程的 CPU 占用率(百分比) + """ + try: + process = psutil.Process(os.getpid()) + cpu_usage = process.cpu_percent(interval=interval) + if isinstance(cpu_usage, (int, float)): + return cpu_usage + else: + logging.error("CPU 使用率数据类型不正确") + return None + except psutil.NoSuchProcess: + logging.error("进程不存在") + return None + except psutil.AccessDenied: + logging.error("权限不足") + return None + except Exception as e: + logging.error(f"未知错误: {e}") + return None + +# 删除目录下的图片文件函数 +def delete_images_in_directory(directory): + """ + 删除指定目录下的所有图片文件。 + + 该函数会遍历指定的目录,寻找并删除所有扩展名在image_extensions列表中的图片文件。 + + 参数: + directory (str): 图片文件所在的目录路径。 + + 返回: + 无返回值。 + """ + # 指定要删除的图片文件扩展名 + image_extensions = ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.tiff'] + + # 遍历目录中的所有文件 + for filename in os.listdir(directory): + # 获取文件的完整路径 + file_path = os.path.join(directory, filename) + + # 检查文件是否为图片文件 + if any(filename.lower().endswith(ext) for ext in image_extensions): + try: + # 删除文件 + os.remove(file_path) + print(f"已删除文件: {file_path}") + except Exception as e: + print(f"删除文件 {file_path} 时出错: {e}") + +# 判断非法字符函数 +def is_valid_password(password): + """ + 验证密码的有效性。 + + 有效密码需满足以下条件: + 1. 必须是一个字符串。 + 2. 长度至少为11个字符。 + 3. 必须包含至少一个小写字母、一个大写字母和一个数字。 + 4. 不得包含连续3位相同的字符。 + 5. 不得包含连续3位连续的字符(如123, abc)。 + + 参数: + password (str): 待验证的密码。 + + 返回: + bool: 如果密码有效则返回True,否则返回False。 + """ + try: + # 基本类型检查 + if not isinstance(password, str): + raise ValueError("Password must be a string") + + # 检查长度,密码至少需要11个字符 + if len(password) < 11: + return False + + # 使用正则表达式检查密码是否包含大小写字母和数字 + if not re.match(r'^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{11,}$', password): + return False + + # 检查连续3位及以上不重复且不连续组合 + for i in range(len(password) - 2): + # 检查是否有连续3位相同 + if password[i] == password[i + 1] == password[i + 2]: + return False + + # 检查是否有连续3位是连续字符(如123, abc) + if abs(ord(password[i + 1]) - ord(password[i])) == 1 and abs(ord(password[i + 2]) - ord(password[i + 1])) == 1: + return False + + return True + except Exception as e: + logging.error(f"An error occurred: {e}") + return False + +# 退出浏览器并释放资源函数 +def browser_quit(): + """ + 退出浏览器并释放资源。 + + 该函数从全局存储中获取浏览器驱动实例,并调用其quit方法来关闭浏览器并释放相关资源。 + """ + # 清除浏览器 + INFO("清除浏览器") + # 从全局存储中获取浏览器驱动实例 + wd = GSTORE['wd'] + # 调用浏览器驱动实例的quit方法,关闭浏览器并释放资源 + wd.quit() + +# 获取最新的HTML报告文件,并拼接网页访问连接函数 +def get_latest_report_file(report_dir, base_url): + """ + 获取指定目录下最新的HTML报告文件,并返回带有基础URL的完整路径。 + + :param report_dir: 报告文件所在的目录 + :param base_url: 基础URL + :return: 最新的HTML报告文件的完整URL,如果没有找到则返回None + """ + # 记录调用此函数的日志 + logging.info("开始调用get_latest_report_file函数获取报告文件") + + # 确保报告目录存在 + if not os.path.exists(report_dir): + logging.error(f"报告目录 {report_dir} 不存在。") + return None + + # 获取指定目录下所有符合模式的HTML报告文件 + report_files = glob.glob(os.path.join(report_dir, 'report_*.html')) + + # 打印找到的文件列表 + logging.debug(f"找到的报告文件: {report_files}") + + # 如果没有找到报告文件,记录警告信息并返回None + if not report_files: + logging.warning("在指定目录中没有找到报告文件。") + return None + + # 找到最新修改的报告文件 + latest_file = max(report_files, key=os.path.getmtime) + + # 获取最新报告文件的最后修改时间 + last_modified_time = datetime.fromtimestamp(os.path.getmtime(latest_file)).strftime('%Y-%m-%d %H:%M:%S') + + # 记录最新报告文件的信息 + logging.info(f"最新报告文件: {latest_file}, 最后修改时间: {last_modified_time}") + + # 将文件路径转换为相对于基础URL的相对路径 + relative_path = os.path.relpath(latest_file, report_dir) + + # 生成完整的URL + full_url = f"{base_url}/{relative_path}".replace("\\", "/") + + # 返回完整的URL + return full_url + +# 钉钉群机器人消息发送函数 +def dingding_send_message(latest_report, title, mobile, ding_type): + """ + 发送钉钉机器人消息 + 参考接口文档:https://open.dingtalk.com/document/orgapp/custom-robots-send-group-messages#title-7fs-kgs-36x + + :param latest_report: 测试报告链接 + :param title: 消息标题 + :param mobile: 需要@的手机号列表 + :param ding_type: 钉钉机器人类型,用于选择不同的 Webhook URL 和密钥 + """ + # 记录调用此函数的日志 + logging.info("开始构建并发送钉钉机器人消息") + # 钉钉机器人的 Webhook URL 和密钥(正式环境) + # webhook_url = 'https://oapi.dingtalk.com/robot/send?access_token=b0eea0bbf097ce3badb4c832d2cd0267a50486f395ec8beca6e2042102bb295b' + # secret = 'SEC928b11659c5fd6476cfa2042edbf56da876abf759289f7e4d3c671fb9a81bf43' + # 钉钉机器人的 Webhook URL 和密钥(测试环境) + + if ding_type == '标准版巡检': + webhook_url = 'https://oapi.dingtalk.com/robot/send?access_token=7fbf40798cad98b1b5db55ff844ba376b1816e80c5777e6f47ae1d9165dacbb4' + secret = 'SEC610498ed6261ae2df1d071d0880aaa70abf5e67efe47f75a809c1f2314e0dbd6' + elif ding_type == '展厅巡检': + webhook_url = 'https://oapi.dingtalk.com/robot/send?access_token=061b6e9b1ae436f356cfda7fe19b6e58e46b62670046a78bd3a4d869118c612d' + secret = 'SEC93212bd880aad638cc0df2b28a72ef4fdf6651cacb8a6a4bc71dcf09705d458d' + + # 生成时间戳 + timestamp = str(round(time.time() * 1000)) + + # 生成签名 + secret_enc = secret.encode('utf-8') + string_to_sign = f'{timestamp}\n{secret}' + string_to_sign_enc = string_to_sign.encode('utf-8') + hmac_code = hmac.new(secret_enc, string_to_sign_enc, digestmod=hashlib.sha256).digest() + sign = urllib.parse.quote_plus(base64.b64encode(hmac_code)) + + # 构建最终的 Webhook URL + params = { + 'access_token': webhook_url.split('=')[1], + 'timestamp': timestamp, + 'sign': sign + } + encoded_params = urllib.parse.urlencode(params) + final_webhook_url = f'https://oapi.dingtalk.com/robot/send?{encoded_params}' + + # 记录最终的 Webhook URL + logging.info(f"钉钉机器人Webhook URL: {final_webhook_url}") + + # 调用测试结果获取函数 + browser_init("标准版预定系统") + wd = GSTORE['wd'] + # print(latest_report) + test_result = get_test_result(latest_report, wd) + browser_quit() + + # 构建消息体 + headers = {'Content-Type': 'application/json'} + message = { + 'msgtype': 'link', + 'link': { + 'title': title, + 'messageUrl': latest_report, + 'text': f"通过:{test_result['pass_percent']}" + f"失败:{test_result['fail_percent']}" + f"异常:{test_result['exception_percent']}", + }, + "at": { + "atMobiles": [mobile], + "isAtAll": True + } + } + + try: + # 发送 POST 请求 + response = requests.post(final_webhook_url, data=json.dumps(message), headers=headers) + + # 检查响应状态码 + if response.status_code == 200: + logging.info('消息发送成功!') + logging.info(f'响应内容: {response.text}') + else: + logging.error(f'消息发送失败,状态码: {response.status_code}') + logging.error(f'响应内容: {response.text}') + except requests.exceptions.RequestException as e: + logging.error(f'请求异常: {e}') + +# 运行自动化测试函数,并调用获取测试报告链接和钉钉机器人消息发送函数 +def run_automation_test(report_title, report_url_prefix, test_case , ding_type): + """ + 运行自动化测试并生成报告。 + + 参数: + - report_title: 报告的标题 + - report_url_prefix: 报告URL的前缀 + - test_case: 测试用例脚本执行的标签名 + - ding_type: 钉钉通知的类型,备用参数,当前代码中未使用 + """ + # 记录测试开始的日志 + logging.info("开始自动化测试...") + + # 构建运行测试命令 + command = [ + 'hytest', + '--report_title', report_title, + '--report_url_prefix', report_url_prefix, + '--tag', test_case + ] + + # 记录将要执行的命令日志 + logging.info(f"执行命令: {' '.join(command)}") + + try: + # 执行测试命令并获取结果 + result = subprocess.run(command, capture_output=True, text=True, check=True) + + # 记录命令的标准输出和错误输出 + logging.debug(f"命令标准输出: {result.stdout}") + logging.debug(f"命令错误输出: {result.stderr}") + except subprocess.CalledProcessError as e: + # 处理子进程调用失败的异常 + logging.error(f"命令执行失败,返回码 {e.returncode}: {e.output}") + except OSError as e: + # 处理操作系统相关的异常 + logging.error(f"发生操作系统错误: {e}") + finally: + # 无论测试是否成功,都记录测试结束的日志 + logging.info("自动化测试完成。") + + # 调用回调函数处理后续操作 + get_reportfile_send_dingding(f"{report_title}", report_url_prefix, ding_type) + +# 定义一个函数,用于获取最新的报告文件,并返回其URL,并调用钉钉消息发送函数 +def get_reportfile_send_dingding(report_title, report_url_prefix, ding_type): + """ + 获取最新的报告文件并通过钉钉发送报告链接。 + + 参数: + report_title (str): 报告的标题。 + report_url_prefix (str): 报告URL的前缀。 + ding_type (str): 钉钉消息的类型。 + + 返回: + 无 + """ + # print(GSTORE['case_pass']) + try: + # 获取报告文件所在的目录 + report_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..','reports') + + # 获取基础URLs + base_url = report_url_prefix + + # 获取最新的报告文件 + latest_report = get_latest_report_file(report_dir, base_url) + + # 如果找到了最新的报告文件,则发送报告链接到钉钉 + if latest_report: + logging.info(f"最新报告文件URL: {latest_report}") + + try: + # 记录调用钉钉消息通知函数的日志 + logging.info("开始调用钉钉消息通知函数") + + # 调用钉钉发送消息接口进行推送测试报告链接 + dingding_send_message(latest_report, report_title, "13724387318", ding_type) + + # 记录钉钉消息通知函数调用成功的日志 + logging.info("钉钉消息通知函数调用成功") + except Exception as e: + # 记录钉钉消息通知函数调用失败的日志 + logging.error(f"钉钉消息通知函数调用失败: {e}") + else: + # 记录没有找到报告文件的日志 + logging.warning("没有找到报告文件以发送。") + + except subprocess.CalledProcessError as e: + # 处理子进程调用失败的异常 + logging.error(f"命令执行失败,返回码 {e.returncode}: {e.output}") + except OSError as e: + # 处理操作系统相关的异常 + logging.error(f"发生操作系统错误: {e}") + finally: + # 无论是否成功,都记录测试结束的日志 + logging.info("自动化测试完成。") + + +from selenium.webdriver.common.action_chains import ActionChains +from selenium.webdriver.support.ui import WebDriverWait +from selenium.webdriver.support import expected_conditions as EC +from selenium.common.exceptions import TimeoutException, NoSuchElementException +# 点击并拖拽函数 +def single_click_and_drag(source_element_locator, target_element_locator, wd): + """ + 实现元素从source_element单击后拖拽到target_element的功能 + + :param wd: WebDriver实例 + :param source_element_locator: 拖拽起始元素的定位器 + :param target_element_locator: 拖拽目标元素的定位器 + """ + try: + # 等待页面完全加载 + sleep(3) + + # 找到源元素和目标元素 + source_element = WebDriverWait(wd, 5).until(EC.element_to_be_clickable(source_element_locator)) + target_element = WebDriverWait(wd, 5).until(EC.element_to_be_clickable(target_element_locator)) + + # 使用ActionChains执行单击并拖拽操作 + actions = ActionChains(wd) + actions.click_and_hold(source_element) # 单击并按住源元素 + actions.move_to_element(target_element) # 移动到目标元素 + actions.release() # 释放鼠标 + actions.perform() + + logging.info("单击并拖拽操作成功") + except TimeoutException as e: + logging.error(f"元素查找超时: {e}") + except NoSuchElementException as e: + logging.error(f"元素未找到: {e}") + except Exception as e: + logging.error(f"发生未知错误: {e}") + +# 获取check.txt文件并解析指定信息函数 +import requests +import os +import chardet +from urllib3.exceptions import InsecureRequestWarning +# 禁用 InsecureRequestWarning 警告 +requests.packages.urllib3.disable_warnings(category=InsecureRequestWarning) +def fetch_and_parse_check_txt(url, save_path, extract_info): + """ + 获取check.txt文件并解析指定信息 + + :param url: check.txt文件的URL + :param save_path: 文件保存路径 + :param extract_info: 需要提取的信息列表,例如 ['[m]ysql', '[r]edis', '[f]dfs_storaged', '[f]dfs_tracker', '[e]mqx', 'ubains-meeting-api-1.0-SNAPSHOT.jar', 'ubains-meeting-inner-api-1.0-SNAPSHOT.jar', 'uwsgi'] + :return: 提取的信息字典 + """ + try: + # 发送HTTPS请求获取文件内容 + response = requests.get(url, verify=False) # verify=False 忽略SSL证书验证,生产环境不推荐 + response.raise_for_status() # 如果响应状态码不是200,抛出异常 + + # 检测文件编码 + detected_encoding = chardet.detect(response.content)['encoding'] + logging.info(f"检测到的编码: {detected_encoding}") + + # 如果检测到的编码为空或不准确,可以手动指定编码 + if not detected_encoding or detected_encoding == 'ascii': + detected_encoding = 'utf-8' # 假设文件编码为 utf-8 + + # 将响应内容解码为字符串 + content = response.content.decode(detected_encoding) + + # 将文件内容保存到指定目录 + with open(save_path, 'w', encoding='utf-8') as file: + file.write(content) + + # 解析文件内容 + parsed_info = {} + for line in content.split('\n'): + for info in extract_info: + if info in line and info not in parsed_info: + service_name = info + service_status = line.split(info, 1)[1].strip() + parsed_info[service_name] = service_status + break # 找到后跳出内层循环,继续处理下一行 + + return parsed_info + + except requests.exceptions.RequestException as e: + logging.exception(f"请求错误: {e}") + return None + +# 检查服务状态函数 +import telnetlib +def check_service_status(host, port): + """ + 检查服务状态。 + + 通过尝试连接到指定的主机和端口来检查服务是否可用。 + + 参数: + - host: 服务所在的主机地址。 + - port: 服务监听的端口。 + + 返回值: + 无 + """ + try: + # 创建Telnet对象并连接到服务器 + tn = telnetlib.Telnet(host, port) + INFO(f"成功连接到 {host}:{port}") + + # 可以在这里发送命令或读取响应 + # 例如,读取服务器的欢迎信息 + response = tn.read_until(b"\n", timeout=5) + INFO(f"服务器响应: {response.decode('ascii')}") + + # 关闭连接 + tn.close() + except Exception as e: + INFO(f"连接失败: {e}") + +# 设置腾讯会议会议号为全局变量函数 +def set_tx_meeting_id(element_locator, wd): + """ + 设置腾讯会议ID到全局存储。 + + 该函数通过元素定位器获取腾讯会议ID,并将其存储在全局变量GSTORE中, + 以便在其他地方访问和使用该ID。 + + 参数: + - element_locator: 用于定位腾讯会议ID元素的定位器。 + - wd: WebDriver实例,用于与网页交互。 + + 返回值: + 无返回值。 + """ + # 获取腾讯会议ID文本 + tx_meeting_id = elment_get_text(element_locator, wd) + # 将腾讯会议ID存储在全局存储中 + GSTORE['tx_meeting_id'] = tx_meeting_id + +# 获取腾讯会议会议号函数 +def get_tx_meeting_id(): + """ + 获取腾讯会议ID。 + + 从全局存储器GSTORE中获取预先存储的腾讯会议ID。这个函数没有输入参数,直接返回存储的会议ID。 + + Returns: + str: 腾讯会议ID。 + """ + return GSTORE.get('tx_meeting_id') + +# 云喇叭设备注册函数 +def voice_device_register(app_id, app_secret, device_sn): + """ + 注册语音设备。 + + 向指定的API发送POST请求,以注册一个语音设备。需要提供应用的ID和密钥,以及设备的序列号。 + + 参数: + app_id (str): 应用的唯一标识符。 + app_secret (str): 应用的秘密密钥。 + device_sn (str): 设备的序列号。 + + 返回: + 无直接返回值,但会记录请求结果到日志。 + """ + # 构建请求体,包含注册所需的必要信息 + body = { + "app_id": app_id, + "app_secret": app_secret, + "device_sn": device_sn + } + + # 设置请求头,指定内容类型为JSON + headers = { + "Content-Type": "application/json" + } + + try: + # 发送POST请求到注册URL,请求体序列化为JSON格式 + response = requests.post("https://wdev.wmj.com.cn/deviceApi/register", headers=headers, data=json.dumps(body)) + # 检查HTTP响应状态码,确保请求成功 + response.raise_for_status() + # 解析响应的JSON内容 + response_json = response.json() + # 记录成功的请求日志 + logging.info("请求成功: %s", response_json) + except requests.exceptions.RequestException as e: + # 处理请求异常,记录错误日志 + logging.error("请求失败: %s", e) + except ValueError as e: + # 处理解析响应异常,记录错误日志 + logging.error("解析响应失败: %s", e) + +# 云喇叭设备设置函数 +import requests +def cloud_voice_setting(app_id, app_secret, device_sn): + """ + 设置云语音功能。 + + :param app_id: 应用ID + :param app_secret: 应用密钥 + :param device_sn: 设备序列号 + :return: 服务器响应结果 + """ + url = "https://wdev.wmj.com.cn/deviceApi/send" + + # 写死的data参数 + data = { + "cmd_type": "setting", + "info": { + "volume": 10, # 0-9,音量由小到大,默认为中间值 + "speed": 2, # 0-9,语速由慢到快,默认为中间值正常语速 + "tone": 4, # 0-9,语调由低到高,默认为中间值正常语调 + "speaker": 0 # 0为女生,支持中英文 + } + } + + # 构建请求体 + payload = { + "app_id": app_id, + "app_secret": app_secret, + "device_sn": device_sn, + "data": data + } + + # 发送POST请求 + try: + response = requests.post(url, json=payload) + response.raise_for_status() # 如果响应状态码不是200,抛出异常 + logging.info(response.json()) # 打印响应的JSON数据 + except requests.exceptions.RequestException as e: + logging.error({"status": "error", "message": str(e)}) + +# 示例调用 +# if __name__ == "__main__": +# app_id = os.getenv("APP_ID", "a98a124c6c3252f6612fc544a0d0fa79") +# app_secret = os.getenv("APP_SECRET", "88bc1ec4eba624f47b2200a4ce8c3852") +# device_sn = os.getenv("DEVICE_SN", "W703BB44444") +# cloud_voice_setting(app_id, app_secret, device_sn) + +# 云喇叭设备播放函数 +def play_cloud_voice(app_id, app_secret, device_sn): + """ + 播放云语音功能。 + + 本函数通过发送HTTP POST请求,触发远程语音设备播放指定的语音内容。 + + 参数: + - app_id: 应用ID,用于标识应用。 + - app_secret: 应用密钥,用于验证应用的身份。 + - device_sn: 设备序列号,用于标识具体的语音设备。 + """ + # 注册设备 + voice_device_register(app_id, app_secret, device_sn) + sleep(5) # 可以考虑使用异步编程或非阻塞的方式替代 + + # 设置云喇叭的音量以及语速参数 + cloud_voice_setting(app_id, app_secret, device_sn) + sleep(10) + + # 定义请求URL + url = os.getenv("CLOUD_VOICE_API_URL", "https://wdev.wmj.com.cn/deviceApi/send") + + # 构建请求体,包括应用ID、应用密钥、设备序列号和语音播放指令 + body = { + "app_id": app_id, + "app_secret": app_secret, + "device_sn": device_sn, + "data": { + "cmd_type": "play", + "info": { + "tts": "一、二、三、四、五、六、七、八、九、十 一、二、三、四、五、六、七、八、九、十 一、二、三、四、五、六、七、八、九、十、一、二、三、四、五、六、七、八、九、十", + "inner": 10, # wifi版特有 + "volume": 5 # 4G版本1-7,wifi版1-10 + } + } + } + + # 设置请求头,指定内容类型为JSON + headers = { + "Content-Type": "application/json" + } + + try: + # 发送POST请求 + response = requests.post(url, headers=headers, data=json.dumps(body)) + + # 根据响应状态码判断请求是否成功 + if response.status_code == 200: + logging.info(f"请求成功: {response.json()}") + else: + logging.error(f"请求失败: 状态码 {response.status_code}, 响应内容 {response.text}") + + except requests.exceptions.RequestException as e: + logging.error(f"请求过程中发生异常: {e}") + except json.JSONDecodeError as e: + logging.error(f"JSON解析失败: {e}") + except Exception as e: + logging.error(f"发生未知异常: {e}") + +# # 示例调用 +# if __name__ == "__main__": +# app_id = os.getenv("APP_ID", "a98a124c6c3252f6612fc544a0d0fa79") +# app_secret = os.getenv("APP_SECRET", "88bc1ec4eba624f47b2200a4ce8c3852") +# device_sn = os.getenv("DEVICE_SN", "W703BB44444") +# play_cloud_voice(app_id, app_secret, device_sn) + +# 获取测试报告通过率等参数的函数 +import logging +import re +from selenium.webdriver.common.by import By +def get_test_result(latest_report, wd): + """ + 获取测试结果页面的通过率、失败率和异常率 + + :param latest_report: 测试结果页面的URL + :param wd: WebDriver实例,用于访问和操作网页 + :return: 包含通过率、失败率和异常率的字典 + """ + # 初始化测试结果字典 + test_result = { + "pass_percent": "", + "fail_percent": "", + "exception_percent": "" + } + + # 访问测试结果页面 + wd.get(latest_report) + sleep(5) + + # 点击简略显示 + safe_click((By.XPATH,"//div[@id='display_mode']"), wd) + sleep(5) + + # 定义一个函数来获取和解析百分比 + def get_percentage(selector, wd): + text = elment_get_text(selector, wd) + logging.info(f"获取的文本:{text}") + match = re.search(r'(\d+(\.\d+)?)%', text) + if match: + return match.group(0) + else: + logging.error(f"未找到百分比匹配项,文本内容: {text}") + return "0" + + # 获取通过率 + pass_percent = get_percentage((By.CSS_SELECTOR, "div[class='result_barchart'] div:nth-child(1) span:nth-child(1)"), wd) + test_result["pass_percent"] = pass_percent + + # 获取失败率 + fail_percent = get_percentage( + (By.CSS_SELECTOR, "body > div.main_section > div.result > div > div:nth-child(2) > span"), wd) + test_result["fail_percent"] = fail_percent + + # 获取异常率 + exception_percent = get_percentage( + (By.CSS_SELECTOR, "body > div.main_section > div.result > div > div:nth-child(3) > span"), wd) + test_result["exception_percent"] = exception_percent + # 输出test_result + logging.info(test_result) + print(test_result) + sleep(5) + + # 返回测试结果字典 + return test_result + +# if __name__ == "__main__": +# browser_init("展厅预定巡检") +# wd = GSTORE['wd'] +# test_result = get_test_result("http://nat.ubainsyun.com:31134/report_20250217_094401.html",wd) +# print(test_result) + +# 获取本机IP地址函数 +import yaml +import logging +import socket +import subprocess +def get_local_ip(): + """ + 获取本机的局域网IP地址。 + + 此函数通过尝试与外部网络通信来确定本机的局域网IP地址。它利用了UDP协议, + 并连接到一个知名的公共IP地址和端口,以此来获取本机的IP地址信息。 + + Returns: + str: 本机的局域网IP地址。 + """ + try: + # 创建一个UDP套接字 + sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + # 连接到一个公共的IP地址和端口 + sock.connect(("8.8.8.8", 80)) + # 获取本地IP地址 + local_ip = sock.getsockname()[0] + finally: + # 确保在所有情况下关闭套接字 + sock.close() + return local_ip + +# 更新ngrok.cfg文件中的IP地址 函数 +def update_ngrok_config(config_path, new_ip): + """ + 更新ngrok配置文件中的IP地址 + + 本函数尝试打开并解析ngrok配置文件,更新其中的IP地址,然后将更改保存回配置文件中 + + 参数: + config_path (str): ngrok配置文件的路径 + new_ip (str): 需要更新到配置文件中的新IP地址 + + 返回: + 无 + """ + try: + # 打开并安全地加载ngrok配置文件 + with open(config_path, 'r', encoding='utf-8') as file: + config = yaml.safe_load(file) + + # 更新IP地址 + config['tunnels']['nat1']['proto']['tcp'] = f"{new_ip}:80" + + # 将更新后的配置安全地写回文件 + with open(config_path, 'w', encoding='utf-8') as file: + yaml.safe_dump(config, file, default_flow_style=False, allow_unicode=True) + + # 记录成功更新的日志信息 + logging.info(f"ngrok.cfg 更新成功,新的IP地址为: {new_ip}") + except Exception as e: + # 记录更新过程中出现的错误 + logging.error(f"更新ngrok.cfg文件时出错: {e}") + +# 启动ngrok函数 +def start_ngrok(ngrok_path, config_path): + """ + 启动ngrok工具。 + + 在尝试启动ngrok之前,此函数会先终止已运行的ngrok进程(如果有的话)。 + 然后使用指定的配置文件路径启动ngrok,并记录启动结果。 + + 参数: + ngrok_path (str): ngrok可执行文件的路径。 + config_path (str): ngrok配置文件的路径。 + + 返回: + 无返回值。 + """ + try: + # 终止已运行的ngrok进程 + kill_ngrok() + + # 构建启动ngrok的命令 + command = [ngrok_path, '-config', config_path, 'start', 'nat1'] + # 使用构建的命令启动ngrok + subprocess.Popen(command, shell=True) + # 记录ngrok启动成功的信息 + logging.info(f"ngrok 启动成功") + except Exception as e: + # 记录启动ngrok时发生的错误 + logging.error(f"启动ngrok时出错: {e}") + +# 停止ngrok进程函数 +def kill_ngrok(): + """ + 尝试终止所有正在运行的ngrok进程。 + """ + try: + # 使用 taskkill 命令终止所有 ngrok 进程 + subprocess.run(['taskkill', '/F', '/IM', 'ngrok.exe'], check=True) + logging.info("终止所有 ngrok 进程成功") + except subprocess.CalledProcessError as e: + # 如果没有找到 ngrok 进程,记录相关信息 + logging.info("没有找到 ngrok 进程") + except Exception as e: + # 如果终止 ngrok 进程时发生其他错误,记录错误信息 + logging.error(f"终止 ngrok 进程时出错: {e}") + +# if __name__ == '__main__': +# logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') +# +# # 获取本机IP地址 +# local_ip = get_local_ip() +# logging.info(f"本机IP地址: {local_ip}") +# +# # 更新ngrok.cfg文件 +# ngrok_config_path = r'D:\GithubData\自动化\ubains-module-test\预定系统\ngrok\ngrok-调试主机\ngrok.cfg' +# update_ngrok_config(ngrok_config_path, local_ip) +# +# # 启动ngrok +# ngrok_path = r'D:\GithubData\自动化\ubains-module-test\预定系统\ngrok\ngrok-调试主机\ngrok.exe' +# start_ngrok(ngrok_path, ngrok_config_path) + +# 字符串转换枚举类型函数 +def get_by_enum(type_str): + """ + 将字符串类型的定位器类型转换为 selenium.webdriver.common.by.By 枚举类型。 + + 参数: + type_str (str): 定位器类型字符串,例如 'XPATH'。 + + 返回: + selenium.webdriver.common.by.By: 对应的 By 枚举类型。 + """ + # 将输入的定位器类型字符串转换为大写,以匹配 By 枚举类型的命名 + type_str = type_str.upper() + + # 根据输入的字符串类型返回对应的 By 枚举类型 + if type_str == 'XPATH': + return By.XPATH + elif type_str == 'ID': + return By.ID + elif type_str == 'NAME': + return By.NAME + elif type_str == 'CLASS_NAME': + return By.CLASS_NAME + elif type_str == 'CSS_SELECTOR': + return By.CSS_SELECTOR + elif type_str == 'TAG_NAME': + return By.TAG_NAME + elif type_str == 'LINK_TEXT': + return By.LINK_TEXT + elif type_str == 'PARTIAL_LINK_TEXT': + return By.PARTIAL_LINK_TEXT + else: + # 如果输入的定位器类型字符串不匹配任何已知的 By 枚举类型,抛出 ValueError 异常 + raise ValueError(f"未知的定位器类型: {type_str}") + +# 获取当前时间并格式化为 'HH:MM' 格式的函数,用于会议预定使用 +import datetime +def get_current_time_formatted(): + """ + 获取当前时间并格式化为 'HH:MM' 格式,并选择最近的未来时间点(如 00:00, 00:15, 00:30, 00:45 等)。 + + 返回: + str: 最近的未来时间点字符串,例如 '17:00'。 + """ + # 获取当前时间 + current_time = datetime.datetime.now() + current_time_formatted = current_time.strftime("%H:%M") + + # 定义时间点列表 + time_points = [ + "00:00", "00:15", "00:30", "00:45", + "01:00", "01:15", "01:30", "01:45", + "02:00", "02:15", "02:30", "02:45", + "03:00", "03:15", "03:30", "03:45", + "04:00", "04:15", "04:30", "04:45", + "05:00", "05:15", "05:30", "05:45", + "06:00", "06:15", "06:30", "06:45", + "07:00", "07:15", "07:30", "07:45", + "08:00", "08:15", "08:30", "08:45", + "09:00", "09:15", "09:30", "09:45", + "10:00", "10:15", "10:30", "10:45", + "11:00", "11:15", "11:30", "11:45", + "12:00", "12:15", "12:30", "12:45", + "13:00", "13:15", "13:30", "13:45", + "14:00", "14:15", "14:30", "14:45", + "15:00", "15:15", "15:30", "15:45", + "16:00", "16:15", "16:30", "16:45", + "17:00", "17:15", "17:30", "17:45", + "18:00", "18:15", "18:30", "18:45", + "19:00", "19:15", "19:30", "19:45", + "20:00", "20:15", "20:30", "20:45", + "21:00", "21:15", "21:30", "21:45", + "22:00", "22:15", "22:30", "22:45", + "23:00", "23:15", "23:30", "23:45" + ] + + # 将当前时间转换为 datetime 对象 + current_time_dt = datetime.datetime.strptime(current_time_formatted, "%H:%M") + + # 初始化最近时间点和最小时间差 + closest_time_point = None + min_time_diff = float('inf') + + # 遍历时间点列表,找到最近的未来时间点 + for time_point in time_points: + time_point_dt = datetime.datetime.strptime(time_point, "%H:%M") + + # 如果时间点在当前时间之后 + if time_point_dt > current_time_dt: + time_diff = (time_point_dt - current_time_dt).total_seconds() + if time_diff < min_time_diff: + min_time_diff = time_diff + closest_time_point = time_point + + # 如果没有找到未来的时间点(即当前时间已经是最后一个时间点),则选择下一个天的最早时间点 + if closest_time_point is None: + closest_time_point = time_points[0] + + return closest_time_point + +# 会议创建函数 +def meeting_message(meeting_room_name, message_type, message_name, wd): + """ + 会议室会议预定功能的实现。 + + 该函数通过模拟用户交互来预定会议室会议。它首先搜索指定的会议室,然后填写会议信息, + 包括会议名称和类型,最后选择会议时间并完成预定。 + + 参数: + - MeetingRoomName (str): 会议室名称,用于搜索指定的会议室。 + - MessageType (str): 会议类型,用于填写会议信息。 + - wd: WebDriver实例,用于操作浏览器。 + + 返回: + 无返回值。 + """ + # 先搜索会议室 + safe_click((By.XPATH, "//i[@class='el-collapse-item__arrow el-icon-arrow-right']"), wd) + sleep(1) + + safe_send_keys((By.XPATH, "//input[@placeholder='请输入会议室名称']"), meeting_room_name, wd) + INFO(f"搜索结果为:{meeting_room_name}") + # 点击【查询】按钮 + safe_click((By.XPATH, "//span[contains(text(),'查询')]"), wd) + sleep(2) + # 点击【会议预定】按钮 + safe_click((By.XPATH, "//span[@class='MeetingCityList_t_btn']"), wd) + sleep(2) + # 输入会议名称并勾选MessageType类型 + safe_send_keys((By.XPATH, "//input[@placeholder='请输入会议名称']"), message_name, wd) + safe_click( + (By.XPATH, f"//div[@class='reserve_input']//span[@class='el-checkbox__label'][contains(text(),'{message_type}')]"), wd) + sleep(1) + # 选择会议时间,点击【快速预定】按钮 + current_time = get_current_time_formatted() + print(f"获取当前的时间{current_time}") + safe_click((By.XPATH, f"//div[normalize-space()='{current_time}']"), wd) + sleep(1) + safe_click((By.XPATH, "//div[@class='header_Quick']"), wd) + safe_click((By.XPATH, "//div[@class='header_Quick']"), wd) + sleep(2) + # 点击【确定】按钮 + safe_click((By.XPATH, "//button[@type='button']//span[contains(text(),'预定')]"), wd) + sleep(2) + +# 会议状态设置函数 +def message_satus_control(message_name, message_type, control_type, wd): + """ + 结束会议流程。 + + 参数: + - message_name: 会议名称,用于搜索特定的会议。 + - message_type: 会议类型,用于判断是否需要进行额外的确认操作。 + - control_type: 控制类型,用于选择相应的会议控制操作。 + - wd: WebDriver实例,用于操作浏览器。 + + 该函数通过模拟用户交互来结束会议,包括搜索会议、点击相关按钮等操作。 + """ + # 输入会议名称并搜索 + safe_send_keys((By.XPATH, "//input[@placeholder='输入关键字搜索']"), message_name, wd) + send_keyboard((By.XPATH, "//input[@placeholder='输入关键字搜索']"), wd) + sleep(2) + # 点击【更多操作】结束会议数据 + # 提前开始会议 + safe_click((By.XPATH, "//span[contains(text(),'更多操作')]"), wd) + sleep(1) + safe_click((By.XPATH, "//li[contains(text(),'会议状态')]"), wd) + sleep(1) + # 选择提前结束 + safe_click((By.XPATH, f"//span[contains(text(),'{control_type}')]"), wd) + sleep(1) + safe_click((By.XPATH, "//div[@slot='footer']//span[contains(text(),'确定')]"), wd) + sleep(2) + # 针对特定会议平台的额外确认操作 + if message_type == "会控": + safe_click((By.XPATH, + "//button[@class='el-button el-button--default el-button--small el-button--primary ']//span[contains(text(),'确定')]"), + wd) + sleep(1) + +# 进入会议预约界面函数 +def enter_meeting_booking_page(meeting_room_name, wd): + """ + 进入会议室预订页面并填写会议信息。 + + :param meeting_room_name: 会议室名称,用于搜索特定的会议室。 + :param wd: WebDriver实例,用于操作浏览器。 + """ + # 先搜索会议室 + safe_click((By.XPATH, "//i[@class='el-collapse-item__arrow el-icon-arrow-right']"), wd) + sleep(1) + + safe_send_keys((By.XPATH, "//input[@placeholder='请输入会议室名称']"), meeting_room_name, wd) + INFO(f"搜索结果为:{meeting_room_name}") + # 点击【查询】按钮 + safe_click((By.XPATH, "//span[contains(text(),'查询')]"), wd) + sleep(2) + # 点击【会议预定】按钮 + safe_click((By.XPATH, "//span[@class='MeetingCityList_t_btn']"), wd) + sleep(2) + # 输入会议名称并勾选MessageType类型 + safe_send_keys((By.XPATH, "//input[@placeholder='请输入会议名称']"), "测试", wd) + sleep(1) + # 选择会议时间 + current_time = get_current_time_formatted() + print(f"获取当前的时间{current_time}") + safe_click((By.XPATH, f"//div[normalize-space()='{current_time}']"), wd) + sleep(1) + +# 删除会议函数 +def del_message(message_name, wd): + """ + 删除会议消息。 + + 根据会议名称搜索并删除会议。 + + 参数: + - message_name: 会议名称,用于搜索特定的会议。 + - wd: WebDriver实例,用于执行网页自动化操作。 + + 此函数无返回值。 + """ + # 输入会议名称并搜索 + safe_send_keys((By.XPATH, "//input[@placeholder='输入关键字搜索']"), message_name, wd) + send_keyboard((By.XPATH, "//input[@placeholder='输入关键字搜索']"), wd) + sleep(2) + # 点击【删除会议】按钮 + safe_click((By.XPATH, "//span[contains(text(),'删除会议')]"), wd) + sleep(2) + # 点击【确定】按钮 + safe_click((By.XPATH, "//button[contains(@class,'el-button el-button--default el-button--small el-button--primary')]//span[contains(text(),'确定')]"), wd) + sleep(1) + # 进入【会议室列表】界面 + safe_click((By.XPATH, "//span[contains(text(),'会议室列表')]"), wd) + sleep(1) \ No newline at end of file Index: 统一平台/config/config.json IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/统一平台/config/config.json b/统一平台/config/config.json new file mode 100644 --- /dev/null (date 1742442537167) +++ b/统一平台/config/config.json (date 1742442537167) @@ -0,0 +1,4 @@ +{ + "_comment_exhibit_unified_platform": "统一平台系统URL", + "统一平台": "http://192.168.5.164:38083/#/login" +} \ No newline at end of file Index: 运维集控/项目测试/运维标准版/cases/01登录模块/管理员登录.py IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.BaseRevisionTextPatchEP <+>from hytest.common import SELENIUM_LOG_SCREEN\r\nfrom win32trace import flush\r\n\r\nfrom 运维集控.项目测试.运维标准版.lib.base import *\r\n\r\n#构建当前项目路径\r\nsys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', '..', '..', '..')))\r\n# 构建 CSV 文件的绝对路径\r\ncsv_path = os.path.abspath(\r\n os.path.join(os.path.dirname(__file__), '..', '..', 'testdata', '01登录模块', '登录信息.csv'))\r\n\r\nclass User_Login:\r\n tags = ['用户登录','管理员登录']\r\n #构建框架的数据集格式\r\n ddt_cases = read_csv_data(csv_path)\r\n\r\n def teststeps(self):\r\n # 获取 WebDriver 实例\r\n wd = GSTORE['wd']\r\n\r\n #从self.para中解构出数据\r\n name = self.name\r\n username, password, captcha, info= self.para\r\n\r\n # 记录当前测试步骤:用户登录\r\n STEP(1, f'{username} 用户登录测试')\r\n # 使用从 CSV 读取的数据进行登录\r\n user_login(username, password, captcha)\r\n\r\n #记录当前测试步骤:输出提示内容\r\n STEP(2, f'预期提示内容为:{info}')\r\n # 记录当前测试步骤:验证是否登录成功\r\n # 等待系统首页的特定元素(如图片)可见\r\n get_menu = WebDriverWait(wd, 10).until(\r\n EC.visibility_of_element_located((By.XPATH, \"//p[@class='el-message__content']\"))\r\n )\r\n get_text = get_menu.text\r\n STEP(3, f'实际获取登录提示内容:{get_text}')\r\n\r\n # 检查点:验证是否跟预定结果一致\r\n CHECK_POINT('校验提示内容是否跟预定结果一致', get_text == info)\r\n # 截图并保存\r\n SELENIUM_LOG_SCREEN(wd, \"50%\")\r\n wd.refresh()\r\n Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/运维集控/项目测试/运维标准版/cases/01登录模块/管理员登录.py b/运维集控/项目测试/运维标准版/cases/01登录模块/管理员登录.py --- a/运维集控/项目测试/运维标准版/cases/01登录模块/管理员登录.py (revision 1114284965c773bf063d20e1486fe7c5aa398274) +++ b/运维集控/项目测试/运维标准版/cases/01登录模块/管理员登录.py (date 1741853543632) @@ -42,3 +42,4 @@ # 截图并保存 SELENIUM_LOG_SCREEN(wd, "50%") wd.refresh() + Index: 统一平台/cases/主流程功能/02创建视讯会议.py IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/统一平台/cases/主流程功能/02创建视讯会议.py b/统一平台/cases/主流程功能/02创建视讯会议.py new file mode 100644 --- /dev/null (date 1742457611067) +++ b/统一平台/cases/主流程功能/02创建视讯会议.py (date 1742457611067) @@ -0,0 +1,45 @@ +import sys +import os + +# 获取当前脚本的绝对路径 +current_dir = os.path.dirname(os.path.abspath(__file__)) +# 构建统一平台的绝对路径 +platform_path = os.path.abspath(os.path.join(current_dir, '..','..','..')) +# 添加路径 +sys.path.append(platform_path) +# 导入模块 +from 统一平台.base.bases import * + +class Unified_Platform_0001: + tags = ['统一平台','创建-视讯会议-立即开始'] + def teststeps(self): + wd = GSTORE['wd'] + safe_click((By.XPATH, "(//img[@class='el-tooltip item'])[3]"),wd) + # 选择融合视讯会议 + INFO("选择融合视讯会议") + # 勾选视讯会议默认选择smc会议 + safe_click((By.XPATH, "//span[contains(text(),'视讯会议')]"),wd) + # 选择腾讯会议 + safe_click((By.XPATH, "//div[@aria-label='checkbox-group']//label[@class='el-checkbox']//span[@class='el-checkbox__inner']"),wd) + + # 选择会议室与参会人 + INFO("选择多会议室与参会人") + safe_send_keys((By.XPATH, "//input[@placeholder='请输入会议室名称']"), '展厅', wd) + send_keyboard((By.XPATH, "//input[@placeholder='请输入会议室名称']"), wd) + # 全选会议室 + safe_click((By.XPATH, "//div[contains(@class,'el-table el-table--fit el-table--enable-row-transition')]//div[contains(@class,'el-table__fixed-header-wrapper')]//span[contains(@class,'el-checkbox__inner')]"),wd) + + # 选择参会人分配对应会议室 + safe_click((By.XPATH, "//div[contains(@class,'meeting_room')]//div[2]//div[2]//img[2]"),wd) + safe_send_keys((By.XPATH, "//input[contains(@placeholder,'请输入关键字搜索')]"), 'pgy', wd) + send_keyboard((By.XPATH, "//input[contains(@placeholder,'请输入关键字搜索')]"), wd) + # 全选搜索的参会人 + safe_click((By.XPATH, "//div[contains(@class,'meeting_user')]//div[contains(@class,'el-table__fixed-header-wrapper')]//span[contains(@class,'el-checkbox__inner')]"),wd) + safe_click((By.XPATH, "//span[contains(text(),'完成')]"),wd) + + # 会议创建,并查看详情 + safe_click((By.XPATH, "//span[contains(text(),'确定创建')]"),wd) + safe_click((By.XPATH, "//span[contains(text(),'查看详情')]"), wd) + # print(f"这是当前窗口句柄{wd.window_handles}") + INFO("请查看会议详情是否正确包含:多会议室、会议号、会议名称、会议时间") + SELENIUM_LOG_SCREEN(wd, "75%") \ No newline at end of file Index: 统一平台/cases/主流程功能/__st__.py IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/统一平台/cases/主流程功能/__st__.py b/统一平台/cases/主流程功能/__st__.py new file mode 100644 --- /dev/null (date 1742442491056) +++ b/统一平台/cases/主流程功能/__st__.py (date 1742442491056) @@ -0,0 +1,34 @@ +import sys +import os +from time import sleep + +# 获取当前脚本的绝对路径 +current_dir = os.path.dirname(os.path.abspath(__file__)) +# 构建统一平台的绝对路径 +platform_path = os.path.abspath(os.path.join(current_dir, '..','..','..')) +# 添加路径 +sys.path.append(platform_path) +# 导入模块 +try: + from 统一平台.base.bases import * +except ModuleNotFoundError as e: + print(f"ModuleNotFoundError: {e}") + print("尝试使用绝对路径导入") + from 统一平台.base.bases import * + +def suite_setup(): + STEP(1, "初始化浏览器") + browser_init("统一平台") + + wd = GSTORE['wd'] + STEP(2, "登录系统") + safe_send_keys((By.XPATH, "//input[@placeholder='手机号/用户名/邮箱']"),"admin@pgy",wd) + safe_send_keys((By.XPATH, "//input[@placeholder='密码']"),"Ubains@13579",wd) + safe_send_keys((By.XPATH, "//input[@placeholder='图形验证']"),"csba",wd) + safe_click((By.XPATH, "//span[@class='el-checkbox__inner']"),wd) + sleep(2) + safe_click((By.XPATH, "//div[@id='pane-1']//div//span[contains(text(),'登录')]"),wd) + sleep(2) + +def suite_teardown(): + browser_quit() \ No newline at end of file Index: 统一平台/cases/主流程功能/01创建本地会议.py IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/统一平台/cases/主流程功能/01创建本地会议.py b/统一平台/cases/主流程功能/01创建本地会议.py new file mode 100644 --- /dev/null (date 1742457571467) +++ b/统一平台/cases/主流程功能/01创建本地会议.py (date 1742457571467) @@ -0,0 +1,88 @@ +import sys +import os + +# 获取当前脚本的绝对路径 +current_dir = os.path.dirname(os.path.abspath(__file__)) +# 构建统一平台的绝对路径 +platform_path = os.path.abspath(os.path.join(current_dir, '..','..','..')) +# 添加路径 +sys.path.append(platform_path) +# 导入模块 +from 统一平台.base.bases import * + +class Unified_Platform_0001: + tags = ['统一平台','创建-本地会议-立即开始'] + def teststeps(self): + wd = GSTORE['wd'] + safe_click((By.XPATH, "//p[contains(text(),'新建会议')]"),wd) + wd.switch_to.window(wd.window_handles[1]) + # 选择会议室 + INFO("选择多会议室与参会人") + safe_send_keys((By.XPATH, "//input[@placeholder='请输入会议室名称']"), '测试会议室', wd) + send_keyboard((By.XPATH, "//input[@placeholder='请输入会议室名称']"), wd) + # 选择测试会议室的前三个 + safe_click((By.XPATH, "//body[1]/div[1]/div[2]/div[1]/div[2]/div[1]/div[2]/div[1]/div[1]/div[4]/div[2]/table[1]/tbody[1]/tr[1]/td[1]/div[1]/label[1]/span[1]/span[1]"),wd) + safe_click((By.XPATH, "//body[1]/div[1]/div[2]/div[1]/div[2]/div[1]/div[2]/div[1]/div[1]/div[4]/div[2]/table[1]/tbody[1]/tr[2]/td[1]/div[1]/label[1]/span[1]/span[1]"), wd) + safe_click((By.XPATH, "//body[1]/div[1]/div[2]/div[1]/div[2]/div[1]/div[2]/div[1]/div[1]/div[4]/div[2]/table[1]/tbody[1]/tr[3]/td[1]/div[1]/label[1]/span[1]/span[1]"), wd) + + # 选择参会人分配到第一个会议室 + safe_click((By.XPATH, "(//img)[7]"),wd) + safe_send_keys((By.XPATH, "//input[contains(@placeholder,'请输入关键字搜索')]"), 'pgy', wd) + send_keyboard((By.XPATH, "//input[contains(@placeholder,'请输入关键字搜索')]"), wd) + # 全选搜索的参会人 + safe_click((By.XPATH, "//div[contains(@class,'meeting_user')]//div[contains(@class,'el-table__fixed-header-wrapper')]//span[contains(@class,'el-checkbox__inner')]"),wd) + safe_click((By.XPATH, "//span[contains(text(),'完成')]"),wd) + + # 选择参会人分配到第二个会议室 + safe_click((By.XPATH, "(//img)[9]"),wd) + safe_send_keys((By.XPATH, "//input[contains(@placeholder,'请输入关键字搜索')]"), '测试', wd) + send_keyboard((By.XPATH, "//input[contains(@placeholder,'请输入关键字搜索')]"), wd) + # 全选搜索的参会人 + safe_click((By.XPATH, "//div[contains(@class,'meeting_user')]//div[contains(@class,'el-table__fixed-header-wrapper')]//span[contains(@class,'el-checkbox__inner')]"),wd) + safe_click((By.XPATH, "//span[contains(text(),'完成')]"),wd) + + # 会议创建,并查看详情 + safe_click((By.XPATH, "//span[contains(text(),'确定创建')]"),wd) + safe_click((By.XPATH, "//span[contains(text(),'查看详情')]"), wd) + # 切换窗口2,转到会议详情界面 + # wd.switch_to.window(wd.window_handles[1]) + INFO("查看会议详情是否正确包含:多会议室、参会人、会议名称、会议时间等信息") + SELENIUM_LOG_SCREEN(wd, "75%") + +class Unified_Platform_0002: + tags = ['统一平台','创建-本地会议-预定会议'] + def teststeps(self): + wd = GSTORE['wd'] + safe_click((By.XPATH, "(//img[@class='el-tooltip item'])[3]"),wd) + # 选择会议室 + INFO("选择多会议室与参会人") + safe_send_keys((By.XPATH, "//input[@placeholder='请输入会议室名称']"), '测试会议室', wd) + send_keyboard((By.XPATH, "//input[@placeholder='请输入会议室名称']"), wd) + # 选择测试会议室的前三个 + safe_click((By.XPATH, "//body[1]/div[1]/div[2]/div[1]/div[2]/div[1]/div[2]/div[1]/div[1]/div[4]/div[2]/table[1]/tbody[1]/tr[1]/td[1]/div[1]/label[1]/span[1]/span[1]"),wd) + safe_click((By.XPATH, "//body[1]/div[1]/div[2]/div[1]/div[2]/div[1]/div[2]/div[1]/div[1]/div[4]/div[2]/table[1]/tbody[1]/tr[2]/td[1]/div[1]/label[1]/span[1]/span[1]"), wd) + safe_click((By.XPATH, "//body[1]/div[1]/div[2]/div[1]/div[2]/div[1]/div[2]/div[1]/div[1]/div[4]/div[2]/table[1]/tbody[1]/tr[3]/td[1]/div[1]/label[1]/span[1]/span[1]"), wd) + + # 选择参会人分配到第一个会议室 + safe_click((By.XPATH, "(//img)[7]"),wd) + safe_send_keys((By.XPATH, "//input[contains(@placeholder,'请输入关键字搜索')]"), 'test', wd) + send_keyboard((By.XPATH, "//input[contains(@placeholder,'请输入关键字搜索')]"), wd) + # 全选搜索的参会人 + safe_click((By.XPATH, "//div[contains(@class,'meeting_user')]//div[contains(@class,'el-table__fixed-header-wrapper')]//span[contains(@class,'el-checkbox__inner')]"),wd) + safe_click((By.XPATH, "//span[contains(text(),'完成')]"),wd) + + # 选择参会人分配到第二个会议室 + safe_click((By.XPATH, "(//img)[9]"),wd) + safe_send_keys((By.XPATH, "//input[contains(@placeholder,'请输入关键字搜索')]"), 'admin', wd) + send_keyboard((By.XPATH, "//input[contains(@placeholder,'请输入关键字搜索')]"), wd) + # 全选搜索的参会人 + safe_click((By.XPATH, "//div[contains(@class,'meeting_user')]//div[contains(@class,'el-table__fixed-header-wrapper')]//span[contains(@class,'el-checkbox__inner')]"),wd) + safe_click((By.XPATH, "//span[contains(text(),'完成')]"),wd) + + # 会议创建,并查看详情 + safe_click((By.XPATH, "//span[contains(text(),'确定创建')]"),wd) + safe_click((By.XPATH, "//span[contains(text(),'查看详情')]"), wd) + # 切换窗口2,转到会议详情界面 + # wd.switch_to.window(wd.window_handles[1]) + INFO("查看会议详情是否正确包含:多会议室、参会人、会议名称、会议时间等信息") + SELENIUM_LOG_SCREEN(wd, "75%") \ No newline at end of file Index: 统一平台/cases/主流程功能/05会议控制.py IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/统一平台/cases/主流程功能/05会议控制.py b/统一平台/cases/主流程功能/05会议控制.py new file mode 100644 --- /dev/null (date 1742457903297) +++ b/统一平台/cases/主流程功能/05会议控制.py (date 1742457903297) @@ -0,0 +1,33 @@ +import sys +import os + +# 获取当前脚本的绝对路径 +current_dir = os.path.dirname(os.path.abspath(__file__)) +# 构建统一平台的绝对路径 +platform_path = os.path.abspath(os.path.join(current_dir, '..','..','..')) +# 添加路径 +sys.path.append(platform_path) +# 导入模块 +from 统一平台.base.bases import * + +class Unified_Platform_0001: + tags = ['统一平台','会议控制'] + def teststeps(self): + wd = GSTORE['wd'] + # 进入会控界面 + safe_click((By.XPATH, "//span[contains(text(),'进入会控')]"), wd) + # 进行多画面设置 + safe_click((By.XPATH, "//div[@class='frames framesActive el-popover__reference']//span[contains(text(),'一画面')]"),wd) + # 设置四画面 + safe_click((By.XPATH, "(//img[@class='img'])[705]"), wd) + + # 会控界面-设备控制 + INFO("关闭第一个会议室终端的摄像头") + safe_click((By.XPATH, "(//img[@title='关闭摄像头'])[1]"), wd) + sleep(1) + safe_click((By.XPATH, "//span[contains(text(),'确定')]"), wd) + SELENIUM_LOG_SCREEN(wd, "75%") + sleep(2) + INFO("开启麦克风") + safe_click((By.XPATH, "(//img[@title='取消静音'])[1]"), wd) + SELENIUM_LOG_SCREEN(wd, "75%") diff --git a/统一平台/base/common_methods.py b/统一平台/base/common_methods.py new file mode 100644 diff --git a/运维集控/项目测试/运维标准版/cases/08设备管理/03查询设备.py b/运维集控/项目测试/运维标准版/cases/08设备管理/03查询设备.py new file mode 100644 diff --git a/运维集控/项目测试/运维标准版/cases/08设备管理/02编辑设备.py b/运维集控/项目测试/运维标准版/cases/08设备管理/02编辑设备.py new file mode 100644 diff --git a/统一平台/base/log_config.py b/统一平台/base/log_config.py new file mode 100644 diff --git a/运维集控/项目测试/运维标准版/cases/08设备管理/04删除设备.py b/运维集控/项目测试/运维标准版/cases/08设备管理/04删除设备.py new file mode 100644 diff --git a/运维集控/项目测试/运维标准版/cases/07类型标签/02编辑标签.py b/运维集控/项目测试/运维标准版/cases/07类型标签/02编辑标签.py new file mode 100644 diff --git a/运维集控/项目测试/运维标准版/cases/07类型标签/03删除标签.py b/运维集控/项目测试/运维标准版/cases/07类型标签/03删除标签.py new file mode 100644