diff --git a/test/tools/check_remote_status.py b/test/tools/check_remote_status.py new file mode 100644 index 0000000..5e075fa --- /dev/null +++ b/test/tools/check_remote_status.py @@ -0,0 +1,26 @@ +import paramiko + +ssh = paramiko.SSHClient() +ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) +ssh.connect("47.108.78.12", port=22, username="root", password="10102442Lb!") + +sftp = ssh.open_sftp() +with sftp.open("/tmp/test_api.py", "w") as f: + f.write("""import requests +s = requests.Session() +r = s.post('http://127.0.0.1/api/login', json={'account': 'xuans', 'password': '12345678'}, headers={'Content-Type': 'application/json'}) +print('LOGIN:', r.status_code, r.text) +print('COOKIES:', s.cookies.get_dict()) + +r2 = s.get('http://127.0.0.1/api/v1/config/status') +print('CONFIG_STATUS:', r2.status_code, r2.text) + +r3 = s.get('http://127.0.0.1/api/v1/config/section/ssl') +print('SSL_SECTION:', r3.status_code, r3.text) +""") +sftp.close() + +stdin, stdout, stderr = ssh.exec_command("python3 /tmp/test_api.py") +print("STDOUT:\n", stdout.read().decode('utf-8')) +print("STDERR:\n", stderr.read().decode('utf-8')) +ssh.close() diff --git a/test/tools/debug_send.py b/test/tools/debug_send.py new file mode 100644 index 0000000..e819389 --- /dev/null +++ b/test/tools/debug_send.py @@ -0,0 +1,59 @@ +# -*- coding: utf-8 -*- +import time, os +from playwright.sync_api import sync_playwright + +with sync_playwright() as p: + browser = p.chromium.launch( + headless=True, + args=[ + '--no-sandbox', + '--ignore-certificate-errors', + '--host-resolver-rules=MAP mail.solit.cn 47.108.78.12, MAP solit.cn 47.108.78.12' + ] + ) + context = browser.new_context(viewport={'width': 1440, 'height': 900}, ignore_https_errors=True) + page = context.new_page() + + page.on('response', lambda res: print('[API RES]', res.status, res.url, res.text()[:200]) if 'email' in res.url or 'send' in res.url else None) + + page.goto('https://mail.solit.cn/#/login', wait_until='networkidle') + inputs = page.locator('.login-content input') + inputs.nth(0).fill('xuans') + inputs.nth(1).fill('12345678') + page.locator('button.login-btn').click() + page.wait_for_timeout(3000) + + page.goto('https://mail.solit.cn/#/editer', wait_until='networkidle') + page.wait_for_timeout(2000) + + # 填写收件人 + to_input = page.locator('.border-less-select input').first + to_input.click() + to_input.fill('testuser2@solit.cn') + page.wait_for_timeout(500) + # 模拟键盘回车和下拉项选择 + page.keyboard.press('Enter') + page.wait_for_timeout(500) + + # 填写主题 + subject_input = page.locator('.subject-row input') + subject_input.fill('全量测试主题') + + # 填写正文 + editor = page.locator('.editor-content') + editor.click() + page.keyboard.type('测试内容123') + page.wait_for_timeout(500) + + # 查看当前表单绑定的数据 + tags = page.locator('.el-select__tags-text, .el-tag') + print('已选收件人标签数量:', tags.count()) + for i in range(tags.count()): + print('Tag:', tags.nth(i).inner_text()) + + # 点击发送 + print('点击发送...') + page.locator('.send-btn').click() + page.wait_for_timeout(4000) + + browser.close() diff --git a/test/tools/run_all_tabs_test.py b/test/tools/run_all_tabs_test.py new file mode 100644 index 0000000..91ac4d8 --- /dev/null +++ b/test/tools/run_all_tabs_test.py @@ -0,0 +1,71 @@ +# -*- coding: utf-8 -*- +import time, os +from playwright.sync_api import sync_playwright + +test_dir = os.path.join(os.getcwd(), 'test-log', 'config_verification_suite') +os.makedirs(test_dir, exist_ok=True) + +with sync_playwright() as p: + browser = p.chromium.launch( + headless=True, + args=[ + '--no-sandbox', + '--ignore-certificate-errors', + '--host-resolver-rules=MAP mail.solit.cn 47.108.78.12, MAP solit.cn 47.108.78.12' + ] + ) + context = browser.new_context(viewport={'width': 1440, 'height': 900}, ignore_https_errors=True) + page = context.new_page() + + page.goto('https://mail.solit.cn/#/login', wait_until='networkidle') + inputs = page.locator('.login-content input') + inputs.nth(0).fill('xuans') + inputs.nth(1).fill('12345678') + page.locator('button.login-btn').click() + page.wait_for_timeout(3000) + + page.locator('.settings-btn').click() + page.wait_for_timeout(1500) + page.locator('#tab-config').click() + page.wait_for_timeout(2000) + + # List all buttons in .config-navigation + btns = page.locator('.config-navigation button') + print('Navigation buttons count:', btns.count()) + for i in range(btns.count()): + text = btns.nth(i).inner_text().strip().replace(chr(10), ' ') + print(f'Btn {i}: {text}') + + # Click Email Config + if btns.count() > 1: + btns.nth(1).click() + page.wait_for_timeout(2000) + page.screenshot(path=os.path.join(test_dir, '03_config_mail.png')) + + # Click SSL Config + if btns.count() > 2: + btns.nth(2).click() + page.wait_for_timeout(2000) + page.screenshot(path=os.path.join(test_dir, '04_config_ssl.png')) + + # Test Plugins tab in settings + page.locator('#tab-plugins').click() + page.wait_for_timeout(2000) + page.screenshot(path=os.path.join(test_dir, '05_plugins.png')) + + # Test Users tab in settings + page.locator('#tab-users').click() + page.wait_for_timeout(2000) + page.screenshot(path=os.path.join(test_dir, '06_users.png')) + + # Test Logs tab in settings + page.locator('#tab-logs').click() + page.wait_for_timeout(2000) + page.screenshot(path=os.path.join(test_dir, '07_logs.png')) + + # Test Security tab in settings + page.locator('#tab-security').click() + page.wait_for_timeout(2000) + page.screenshot(path=os.path.join(test_dir, '08_security.png')) + + browser.close() diff --git a/test/tools/run_config_test.py b/test/tools/run_config_test.py new file mode 100644 index 0000000..f086c39 --- /dev/null +++ b/test/tools/run_config_test.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- +import time, os +from playwright.sync_api import sync_playwright + +test_dir = os.path.join(os.getcwd(), 'test-log', 'config_verification_suite') +os.makedirs(test_dir, exist_ok=True) + +with sync_playwright() as p: + browser = p.chromium.launch( + headless=True, + args=[ + '--no-sandbox', + '--ignore-certificate-errors', + '--host-resolver-rules=MAP mail.solit.cn 47.108.78.12, MAP solit.cn 47.108.78.12' + ] + ) + context = browser.new_context(viewport={'width': 1440, 'height': 900}, ignore_https_errors=True) + page = context.new_page() + + page.goto('https://mail.solit.cn/#/login', wait_until='networkidle') + inputs = page.locator('.login-content input') + inputs.nth(0).fill('xuans') + inputs.nth(1).fill('12345678') + page.locator('button.login-btn').click() + page.wait_for_timeout(3000) + + page.locator('.settings-btn').click() + page.wait_for_timeout(1500) + page.screenshot(path=os.path.join(test_dir, '01_settings_drawer.png')) + + items = page.locator('.el-tabs__item') + print('Tabs count:', items.count()) + for i in range(items.count()): + text = items.nth(i).inner_text().replace(chr(10), ' ') + print(f'Tab {i}: {text}') + + config_tab = page.locator('#tab-config') + print('Config tab count:', config_tab.count()) + if config_tab.count() > 0: + config_tab.click() + page.wait_for_timeout(2000) + page.screenshot(path=os.path.join(test_dir, '02_config_base.png')) + + browser.close() diff --git a/test/tools/test_check_outbox.py b/test/tools/test_check_outbox.py new file mode 100644 index 0000000..2807e71 --- /dev/null +++ b/test/tools/test_check_outbox.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +import time, os +from playwright.sync_api import sync_playwright + +test_dir = os.path.join(os.getcwd(), 'test-log', 'mail_flow_suite') +os.makedirs(test_dir, exist_ok=True) + +with sync_playwright() as p: + browser = p.chromium.launch( + headless=True, + args=[ + '--no-sandbox', + '--ignore-certificate-errors', + '--host-resolver-rules=MAP mail.solit.cn 47.108.78.12, MAP solit.cn 47.108.78.12' + ] + ) + context = browser.new_context(viewport={'width': 1440, 'height': 900}, ignore_https_errors=True) + page = context.new_page() + + page.on('response', lambda res: print('[API]', res.status, res.url, res.text()[:250]) if 'email' in res.url or 'group' in res.url else None) + + page.goto('https://mail.solit.cn/#/login', wait_until='networkidle') + inputs = page.locator('.login-content input') + inputs.nth(0).fill('xuans') + inputs.nth(1).fill('12345678') + page.locator('button.login-btn').click() + page.wait_for_timeout(3000) + + # 打印菜单项 + menu_items = page.locator('.sidebar-menu .el-menu-item') + print('侧边栏菜单项数:', menu_items.count()) + for i in range(menu_items.count()): + print(f'Menu {i}:', menu_items.nth(i).inner_text().strip()) + + # 点击发件箱 / 已发送 + if menu_items.count() > 1: + menu_items.nth(1).click() + page.wait_for_timeout(2000) + page.screenshot(path=os.path.join(test_dir, '25_outbox_clicked.png')) + + browser.close() diff --git a/test/tools/test_log_audit.py b/test/tools/test_log_audit.py new file mode 100644 index 0000000..b11075c --- /dev/null +++ b/test/tools/test_log_audit.py @@ -0,0 +1,59 @@ +# -*- coding: utf-8 -*- +import time, os +from playwright.sync_api import sync_playwright + +test_dir = os.path.join(os.getcwd(), 'test-log', 'log_audit_suite') +os.makedirs(test_dir, exist_ok=True) + +with sync_playwright() as p: + browser = p.chromium.launch( + headless=True, + args=[ + '--no-sandbox', + '--ignore-certificate-errors', + '--host-resolver-rules=MAP mail.solit.cn 47.108.78.12, MAP solit.cn 47.108.78.12' + ] + ) + context = browser.new_context(viewport={'width': 1440, 'height': 900}, ignore_https_errors=True) + page = context.new_page() + + page.on('response', lambda res: print('[API]', res.status, res.url) if 'log' in res.url or 'audit' in res.url else None) + + page.goto('https://mail.solit.cn/#/login', wait_until='networkidle') + inputs = page.locator('.login-content input') + inputs.nth(0).fill('xuans') + inputs.nth(1).fill('12345678') + page.locator('button.login-btn').click() + page.wait_for_timeout(3000) + + # 打开设置抽屉 + page.locator('.settings-btn').click() + page.wait_for_timeout(1500) + page.locator('#tab-logs').click() + page.wait_for_timeout(2000) + page.screenshot(path=os.path.join(test_dir, '01_logs_overview.png')) + + # 查看日志页面中的子菜单/选项卡 + log_tabs = page.locator('.log-settings button, .settings-submenu-item') + print('日志导航选项数量:', log_tabs.count()) + for i in range(log_tabs.count()): + t = log_tabs.nth(i).inner_text().strip().replace('\n', ' ') + print(f'Tab {i}: {t}') + + # 查看运行日志表格 + rows = page.locator('.el-table__row') + print('当前日志行数:', rows.count()) + for i in range(min(5, rows.count())): + print(f'Row {i}:', rows.nth(i).inner_text().replace('\n', ' | ')) + + # 切换子菜单查看操作日志和收发信日志(如果有) + if log_tabs.count() > 1: + log_tabs.nth(1).click() + page.wait_for_timeout(2000) + page.screenshot(path=os.path.join(test_dir, '02_log_subtab1.png')) + if log_tabs.count() > 2: + log_tabs.nth(2).click() + page.wait_for_timeout(2000) + page.screenshot(path=os.path.join(test_dir, '03_log_subtab2.png')) + + browser.close() diff --git a/test/tools/test_log_categories.py b/test/tools/test_log_categories.py new file mode 100644 index 0000000..ea62cf6 --- /dev/null +++ b/test/tools/test_log_categories.py @@ -0,0 +1,69 @@ +# -*- coding: utf-8 -*- +import time, os +from playwright.sync_api import sync_playwright + +test_dir = os.path.join(os.getcwd(), 'test-log', 'log_audit_suite') +os.makedirs(test_dir, exist_ok=True) + +with sync_playwright() as p: + browser = p.chromium.launch( + headless=True, + args=[ + '--no-sandbox', + '--ignore-certificate-errors', + '--host-resolver-rules=MAP mail.solit.cn 47.108.78.12, MAP solit.cn 47.108.78.12' + ] + ) + context = browser.new_context(viewport={'width': 1440, 'height': 900}, ignore_https_errors=True) + page = context.new_page() + + page.goto('https://mail.solit.cn/#/login', wait_until='networkidle') + inputs = page.locator('.login-content input') + inputs.nth(0).fill('xuans') + inputs.nth(1).fill('12345678') + page.locator('button.login-btn').click() + page.wait_for_timeout(3000) + + # 打开设置抽屉并进入日志 + page.locator('.settings-btn').click() + page.wait_for_timeout(1500) + page.locator('#tab-logs').click() + page.wait_for_timeout(2000) + + # 查看三大单选按钮 + radio_btns = page.locator('.log-categories .el-radio-button') + print('单选按钮数量:', radio_btns.count()) + for i in range(radio_btns.count()): + print(f'Radio {i}:', radio_btns.nth(i).inner_text()) + + # 1. 点击“运行日志” + run_btn = page.locator('.log-categories .el-radio-button:has-text("运行日志")') + if run_btn.count() > 0: + run_btn.click() + page.wait_for_timeout(2000) + page.screenshot(path=os.path.join(test_dir, '10_runtime_logs.png')) + + # 点击第一条运行日志的“查看”按钮 + view_btn = page.locator('.runtime-table .el-button--primary').first + if view_btn.count() > 0: + view_btn.click() + page.wait_for_timeout(1000) + page.screenshot(path=os.path.join(test_dir, '11_runtime_detail_dialog.png')) + # 关闭弹窗 + page.keyboard.press('Escape') + page.wait_for_timeout(500) + + # 2. 点击“收发信日志” + mail_btn = page.locator('.log-categories .el-radio-button:has-text("收发")') + if mail_btn.count() > 0: + mail_btn.click() + page.wait_for_timeout(2000) + page.screenshot(path=os.path.join(test_dir, '20_mail_logs.png')) + + # 检查刚刚发送邮件的收发信日志 + rows = page.locator('.log-table .el-table__row') + print('收发信日志行数:', rows.count()) + for i in range(min(5, rows.count())): + print(f'Mail Log {i}:', rows.nth(i).inner_text().replace('\n', ' | ')) + + browser.close() diff --git a/test/tools/test_mail_send_flow.py b/test/tools/test_mail_send_flow.py new file mode 100644 index 0000000..2a2fa44 --- /dev/null +++ b/test/tools/test_mail_send_flow.py @@ -0,0 +1,73 @@ +# -*- coding: utf-8 -*- +import time, os +from playwright.sync_api import sync_playwright + +test_dir = os.path.join(os.getcwd(), 'test-log', 'mail_flow_suite') +os.makedirs(test_dir, exist_ok=True) + +with sync_playwright() as p: + browser = p.chromium.launch( + headless=True, + args=[ + '--no-sandbox', + '--ignore-certificate-errors', + '--host-resolver-rules=MAP mail.solit.cn 47.108.78.12, MAP solit.cn 47.108.78.12' + ] + ) + context = browser.new_context(viewport={'width': 1440, 'height': 900}, ignore_https_errors=True) + page = context.new_page() + + page.on('response', lambda res: print('[API]', res.status, res.url) if 'api' in res.url else None) + + page.goto('https://mail.solit.cn/#/login', wait_until='networkidle') + inputs = page.locator('.login-content input') + inputs.nth(0).fill('xuans') + inputs.nth(1).fill('12345678') + page.locator('button.login-btn').click() + page.wait_for_timeout(3000) + + # 查看侧边栏并点击“写邮件”或路由切换到 /editer + page.goto('https://mail.solit.cn/#/editer', wait_until='networkidle') + page.wait_for_timeout(2000) + page.screenshot(path=os.path.join(test_dir, '01_editer_page.png')) + + # 查看发件人信息 + sender_info = page.locator('.sender-selector').inner_text() + print('当前发件人展示:', sender_info) + + # 填写收件人 + # 收件人是一个 el-select 允许输入的 + to_input = page.locator('.border-less-select input').first + to_input.fill('testuser2@solit.cn') + page.keyboard.press('Enter') + page.wait_for_timeout(500) + + # 填写主题 + subject_input = page.locator('.subject-row input') + subject_input.fill('全量测试验收邮件 - ' + str(int(time.time()))) + + # 在富文本编辑器中输入正文 + editor = page.locator('.editor-content') + editor.click() + page.keyboard.type('这是一封用于全量功能与发件箱归档测试的真实邮件内容。') + page.wait_for_timeout(500) + page.screenshot(path=os.path.join(test_dir, '02_mail_filled.png')) + + # 点击发送 + print('点击发送邮件...') + page.locator('.send-btn').click() + page.wait_for_timeout(4000) + page.screenshot(path=os.path.join(test_dir, '03_after_send.png')) + print('当前页面 URL:', page.url) + + # 查看发件箱 + print('切换至发件箱...') + # 查找侧边栏中名为“已发送”或“发件箱”的菜单项 + outbox_item = page.locator('.sidebar-menu .el-menu-item:has-text("已发送"), .sidebar-menu .el-menu-item:has-text("发件箱")') + print('发件箱菜单数量:', outbox_item.count()) + if outbox_item.count() > 0: + outbox_item.first.click() + page.wait_for_timeout(2500) + page.screenshot(path=os.path.join(test_dir, '04_outbox_list.png')) + + browser.close() diff --git a/test/tools/test_security_flow.py b/test/tools/test_security_flow.py new file mode 100644 index 0000000..b92197c --- /dev/null +++ b/test/tools/test_security_flow.py @@ -0,0 +1,65 @@ +# -*- coding: utf-8 -*- +import time, os +from playwright.sync_api import sync_playwright + +test_dir = os.path.join(os.getcwd(), 'test-log', 'security_verification_suite') +os.makedirs(test_dir, exist_ok=True) + +with sync_playwright() as p: + browser = p.chromium.launch( + headless=True, + args=[ + '--no-sandbox', + '--ignore-certificate-errors', + '--host-resolver-rules=MAP mail.solit.cn 47.108.78.12, MAP solit.cn 47.108.78.12' + ] + ) + context = browser.new_context(viewport={'width': 1440, 'height': 900}, ignore_https_errors=True) + page = context.new_page() + + page.goto('https://mail.solit.cn/#/login', wait_until='networkidle') + inputs = page.locator('.login-content input') + inputs.nth(0).fill('xuans') + inputs.nth(1).fill('12345678') + page.locator('button.login-btn').click() + page.wait_for_timeout(3000) + + page.locator('.settings-btn').click() + page.wait_for_timeout(1500) + page.locator('#tab-security').click() + page.wait_for_timeout(2000) + page.screenshot(path=os.path.join(test_dir, '01_security_tab.png')) + + # 查找安全中心内所有的按钮或卡片操作 + btns = page.locator('.settings-drawer button') + print('Buttons in settings drawer:', btns.count()) + for i in range(btns.count()): + t = btns.nth(i).inner_text().strip().replace('\n', ' ') + if t: + print(f'Btn {i}: {t}') + + # 寻找设置密保按钮 + set_q_btn = page.locator('button:has-text("密保")') + print('密保按钮数量:', set_q_btn.count()) + if set_q_btn.count() > 0: + set_q_btn.first.click() + page.wait_for_timeout(1500) + page.screenshot(path=os.path.join(test_dir, '02_question_dialog.png')) + + dialog = page.locator('.el-dialog') + d_inputs = dialog.locator('input') + print('弹窗内输入框数量:', d_inputs.count()) + if d_inputs.count() >= 2: + d_inputs.nth(0).fill('幸运数字') + d_inputs.nth(1).fill('8') + page.wait_for_timeout(500) + page.screenshot(path=os.path.join(test_dir, '03_question_filled.png')) + + confirm_btn = dialog.locator('button:has-text("确定"), button:has-text("保存")') + print('确定按钮数量:', confirm_btn.count()) + if confirm_btn.count() > 0: + confirm_btn.last.click() + page.wait_for_timeout(2500) + page.screenshot(path=os.path.join(test_dir, '04_after_question_save.png')) + + browser.close() diff --git a/test/tools/test_security_question.py b/test/tools/test_security_question.py new file mode 100644 index 0000000..a854f96 --- /dev/null +++ b/test/tools/test_security_question.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +import time, os +from playwright.sync_api import sync_playwright + +test_dir = os.path.join(os.getcwd(), 'test-log', 'security_verification_suite') +os.makedirs(test_dir, exist_ok=True) + +with sync_playwright() as p: + browser = p.chromium.launch( + headless=True, + args=[ + '--no-sandbox', + '--ignore-certificate-errors', + '--host-resolver-rules=MAP mail.solit.cn 47.108.78.12, MAP solit.cn 47.108.78.12' + ] + ) + context = browser.new_context(viewport={'width': 1440, 'height': 900}, ignore_https_errors=True) + page = context.new_page() + + page.goto('https://mail.solit.cn/#/login', wait_until='networkidle') + inputs = page.locator('.login-content input') + inputs.nth(0).fill('xuans') + inputs.nth(1).fill('12345678') + page.locator('button.login-btn').click() + page.wait_for_timeout(3000) + + page.locator('.settings-btn').click() + page.wait_for_timeout(1500) + page.locator('#tab-security').click() + page.wait_for_timeout(2000) + + # 点击左侧子菜单中的“密保问题” + question_nav = page.locator('.security-workspace .settings-submenu-item:has-text("密保"), .security-workspace button:has-text("密保")') + print('密保菜单数量:', question_nav.count()) + if question_nav.count() > 0: + question_nav.first.click() + page.wait_for_timeout(1500) + page.screenshot(path=os.path.join(test_dir, '10_security_question_section.png')) + + # 在表单中输入密保问题和 1 位密保答案 + inputs = page.locator('.security-main input') + print('安全主体输入框数量:', inputs.count()) + if inputs.count() >= 2: + inputs.nth(0).fill('幸运数字') + inputs.nth(1).fill('8') + page.wait_for_timeout(500) + page.screenshot(path=os.path.join(test_dir, '11_question_filled_1char.png')) + + # 点击保存/更新密保问题按钮 + save_btn = page.locator('.security-main button.el-button--primary') + print('保存按钮数量:', save_btn.count()) + if save_btn.count() > 0: + save_btn.first.click() + page.wait_for_timeout(2500) + page.screenshot(path=os.path.join(test_dir, '12_question_saved_result.png')) + + browser.close() diff --git a/test/tools/test_send_and_verify.py b/test/tools/test_send_and_verify.py new file mode 100644 index 0000000..0b6d346 --- /dev/null +++ b/test/tools/test_send_and_verify.py @@ -0,0 +1,78 @@ +# -*- coding: utf-8 -*- +import time, os +from playwright.sync_api import sync_playwright + +test_dir = os.path.join(os.getcwd(), 'test-log', 'mail_flow_suite') +os.makedirs(test_dir, exist_ok=True) + +with sync_playwright() as p: + browser = p.chromium.launch( + headless=True, + args=[ + '--no-sandbox', + '--ignore-certificate-errors', + '--host-resolver-rules=MAP mail.solit.cn 47.108.78.12, MAP solit.cn 47.108.78.12' + ] + ) + context = browser.new_context(viewport={'width': 1440, 'height': 900}, ignore_https_errors=True) + page = context.new_page() + + page.on('response', lambda res: print('[API RES]', res.status, res.url, res.text()[:200]) if 'email' in res.url or 'send' in res.url else None) + + page.goto('https://mail.solit.cn/#/login', wait_until='networkidle') + inputs = page.locator('.login-content input') + inputs.nth(0).fill('xuans') + inputs.nth(1).fill('12345678') + page.locator('button.login-btn').click() + page.wait_for_timeout(3000) + + page.goto('https://mail.solit.cn/#/editer', wait_until='networkidle') + page.wait_for_timeout(2000) + + # 聚焦到收件人输入框 + wrapper = page.locator('.border-less-select .el-select__wrapper').first + wrapper.click() + page.wait_for_timeout(300) + + to_input = page.locator('.border-less-select input').first + to_input.fill('testuser2@solit.cn') + page.wait_for_timeout(300) + page.keyboard.press('Enter') + page.wait_for_timeout(500) + + # 填写主题 + subject_input = page.locator('.subject-row input') + subject_input.fill('全量测试邮件主题 - 自动化验证') + + # 填写正文 + editor = page.locator('.editor-content') + editor.click() + page.keyboard.type('测试内容:这是由全量验收流程发送的正式测试邮件。') + page.wait_for_timeout(500) + page.screenshot(path=os.path.join(test_dir, '10_mail_composed.png')) + + # 查看当前已选收件人标签 + tags = page.locator('.border-less-select .el-tag') + print('已选收件人标签数量:', tags.count()) + for i in range(tags.count()): + print('Tag:', tags.nth(i).inner_text()) + + # 点击发送按钮 + print('点击发送邮件...') + page.locator('.send-btn').click() + page.wait_for_timeout(5000) + page.screenshot(path=os.path.join(test_dir, '11_after_send.png')) + print('发送后当前页面 URL:', page.url) + + # 检查已发送列表 + page.goto('https://mail.solit.cn/#/list?tag=outbox', wait_until='networkidle') + page.wait_for_timeout(2000) + page.screenshot(path=os.path.join(test_dir, '12_outbox_list.png')) + + # 查看列表中的邮件 + items = page.locator('.email-item, .mail-item, tr.el-table__row') + print('已发送列表条目数:', items.count()) + for i in range(min(5, items.count())): + print(f'Mail {i}:', items.nth(i).inner_text().replace('\n', ' | ')) + + browser.close() diff --git a/test/tools/test_send_interaction.py b/test/tools/test_send_interaction.py new file mode 100644 index 0000000..bc47827 --- /dev/null +++ b/test/tools/test_send_interaction.py @@ -0,0 +1,78 @@ +# -*- coding: utf-8 -*- +import time, os +from playwright.sync_api import sync_playwright + +test_dir = os.path.join(os.getcwd(), 'test-log', 'mail_flow_suite') +os.makedirs(test_dir, exist_ok=True) + +with sync_playwright() as p: + browser = p.chromium.launch( + headless=True, + args=[ + '--no-sandbox', + '--ignore-certificate-errors', + '--host-resolver-rules=MAP mail.solit.cn 47.108.78.12, MAP solit.cn 47.108.78.12' + ] + ) + context = browser.new_context(viewport={'width': 1440, 'height': 900}, ignore_https_errors=True) + page = context.new_page() + + page.on('response', lambda res: print('[API RES]', res.status, res.url, res.text()[:200]) if 'send' in res.url else None) + + page.goto('https://mail.solit.cn/#/login', wait_until='networkidle') + inputs = page.locator('.login-content input') + inputs.nth(0).fill('xuans') + inputs.nth(1).fill('12345678') + page.locator('button.login-btn').click() + page.wait_for_timeout(3000) + + page.goto('https://mail.solit.cn/#/editer', wait_until='networkidle') + page.wait_for_timeout(2000) + + # 模拟真实在 el-select 内部输入并点击创建选项 + select_box = page.locator('.border-less-select') + select_box.click() + page.wait_for_timeout(300) + page.keyboard.type('testuser2@solit.cn') + page.wait_for_timeout(500) + + # 检查下拉列表中出现的“创建”选项或按 Enter + page.screenshot(path=os.path.join(test_dir, '20_typing_receiver.png')) + # 查看是否有 el-select-dropdown__item + dropdown_item = page.locator('.el-select-dropdown__item:visible') + print('下拉选项数量:', dropdown_item.count()) + if dropdown_item.count() > 0: + dropdown_item.first.click() + else: + page.keyboard.press('Enter') + page.wait_for_timeout(500) + page.screenshot(path=os.path.join(test_dir, '21_receiver_selected.png')) + + # 填写主题 + subject_input = page.locator('.subject-row input') + subject_input.fill('全量测试邮件主题 - 自动化验证') + + # 填写正文 + editor = page.locator('.editor-content') + editor.click() + page.keyboard.type('测试内容:这是由全量验收流程发送的正式测试邮件。') + page.wait_for_timeout(500) + page.screenshot(path=os.path.join(test_dir, '22_ready_to_send.png')) + + # 查看标签 + tags = page.locator('.border-less-select .el-tag') + print('已选收件人标签数量:', tags.count()) + + # 点击发送 + print('点击发送邮件...') + page.locator('.send-btn').click() + page.wait_for_timeout(5000) + page.screenshot(path=os.path.join(test_dir, '23_after_send.png')) + print('当前页面 URL:', page.url) + + # 检查发件箱 + page.goto('https://mail.solit.cn/#/list?tag={"type":1,"status":-1}', wait_until='networkidle') + page.wait_for_timeout(2000) + page.screenshot(path=os.path.join(test_dir, '24_outbox.png')) + + browser.close() diff --git a/test/tools/test_user_debug.py b/test/tools/test_user_debug.py new file mode 100644 index 0000000..25d7a16 --- /dev/null +++ b/test/tools/test_user_debug.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +import time, os +from playwright.sync_api import sync_playwright + +test_dir = os.path.join(os.getcwd(), 'test-log', 'user_management_suite') +os.makedirs(test_dir, exist_ok=True) + +with sync_playwright() as p: + browser = p.chromium.launch( + headless=True, + args=[ + '--no-sandbox', + '--ignore-certificate-errors', + '--host-resolver-rules=MAP mail.solit.cn 47.108.78.12, MAP solit.cn 47.108.78.12' + ] + ) + context = browser.new_context(viewport={'width': 1440, 'height': 900}, ignore_https_errors=True) + page = context.new_page() + + page.on('response', lambda res: print('[API]', res.status, res.url, res.text()[:200]) if 'user' in res.url else None) + + page.goto('https://mail.solit.cn/#/login', wait_until='networkidle') + inputs = page.locator('.login-content input') + inputs.nth(0).fill('xuans') + inputs.nth(1).fill('12345678') + page.locator('button.login-btn').click() + page.wait_for_timeout(3000) + + page.locator('.settings-btn').click() + page.wait_for_timeout(1500) + page.locator('#tab-users').click() + page.wait_for_timeout(2000) + + # 再次新建一个用户测试响应 + page.locator('.new-btn').click() + page.wait_for_timeout(1000) + dialog = page.locator('.el-dialog:visible') + d_inputs = dialog.locator('input') + d_inputs.nth(0).fill('testuser2') + d_inputs.nth(1).fill('测试员二') + d_inputs.nth(2).fill('Test123456') + page.wait_for_timeout(500) + dialog.locator('button.el-button--primary:has-text("确定"), button.el-button--primary:has-text("确认")').click() + page.wait_for_timeout(3000) + + # 查看当前表格 + rows = page.locator('.modern-table .el-table__row') + print('最新用户列表总行数:', rows.count()) + for i in range(rows.count()): + print(f'Row {i}:', rows.nth(i).inner_text().replace('\n', ' | ')) + + browser.close() diff --git a/test/tools/test_user_management.py b/test/tools/test_user_management.py new file mode 100644 index 0000000..d1f460b --- /dev/null +++ b/test/tools/test_user_management.py @@ -0,0 +1,68 @@ +# -*- coding: utf-8 -*- +import time, os +from playwright.sync_api import sync_playwright + +test_dir = os.path.join(os.getcwd(), 'test-log', 'user_management_suite') +os.makedirs(test_dir, exist_ok=True) + +with sync_playwright() as p: + browser = p.chromium.launch( + headless=True, + args=[ + '--no-sandbox', + '--ignore-certificate-errors', + '--host-resolver-rules=MAP mail.solit.cn 47.108.78.12, MAP solit.cn 47.108.78.12' + ] + ) + context = browser.new_context(viewport={'width': 1440, 'height': 900}, ignore_https_errors=True) + page = context.new_page() + + page.goto('https://mail.solit.cn/#/login', wait_until='networkidle') + inputs = page.locator('.login-content input') + inputs.nth(0).fill('xuans') + inputs.nth(1).fill('12345678') + page.locator('button.login-btn').click() + page.wait_for_timeout(3000) + + # 打开设置抽屉 + page.locator('.settings-btn').click() + page.wait_for_timeout(1500) + page.locator('#tab-users').click() + page.wait_for_timeout(2000) + page.screenshot(path=os.path.join(test_dir, '01_users_table.png')) + + # 打印表格表头和行数据 + rows = page.locator('.modern-table .el-table__row') + print('用户行数:', rows.count()) + for i in range(rows.count()): + print(f'Row {i}:', rows.nth(i).inner_text().replace('\n', ' | ')) + + # 点击“新建”按钮 + new_btn = page.locator('.new-btn, button:has-text("新建")') + print('新建按钮数量:', new_btn.count()) + if new_btn.count() > 0: + new_btn.first.click() + page.wait_for_timeout(1000) + page.screenshot(path=os.path.join(test_dir, '02_create_user_dialog.png')) + + # 填写新用户信息 + dialog = page.locator('.el-dialog:visible') + d_inputs = dialog.locator('input') + print('对话框输入框数量:', d_inputs.count()) + # 0: account, 1: name, 2: password + if d_inputs.count() >= 3: + d_inputs.nth(0).fill('tester01') + d_inputs.nth(1).fill('测试员') + d_inputs.nth(2).fill('Tester123456!') + page.wait_for_timeout(500) + page.screenshot(path=os.path.join(test_dir, '03_form_filled.png')) + + # 点击确认按钮 + confirm_btn = dialog.locator('button.el-button--primary:has-text("确定"), button.el-button--primary:has-text("确认")') + print('确认按钮数量:', confirm_btn.count()) + if confirm_btn.count() > 0: + confirm_btn.last.click() + page.wait_for_timeout(2500) + page.screenshot(path=os.path.join(test_dir, '04_after_user_created.png')) + + browser.close()