卷王问卷考试系统 -测试报告
一.项目背景
1.1 项目简介:
卷王是一套覆盖问卷、考试、测评、投票和数据分析的专业系统。既可以把它当作一套日常信息收集工具,也可以把它用于更专业的调研、考试和评估场景。
1.2 项目测试目标:
验证系统核心业务流程的正确性与稳定性
在无需求文档的情况下,通过探索性测试+反向推导,发现潜在缺陷
评估系统质量风险,为上线决策提供参考
1.3 项目链接:
网页链接:首页 - 卷王问卷考试系统
二.测试环境与工具
三.测试分类
3.1 测试用例设计(部分)
3.1.1登录功能
3.1.2首页
3.1.3我的项目页面
3.1.4我的练习页面
3.1.5题库中心界面![]()
3.2 手动功能测试(部分)
登录
正常登录
异常登录
注册
正常注册
异常注册
项目
新建项目正常
搜索栏可正常搜索项目
项目重命名正常
![]()
项目发布正常![]()
项目复制正常
项目删除正常
下载模板正常
3.3 性能测试
页面加载性能测试(主功能模块)
页面弱网测试(首页)
3.4 安全测试
因本项目只有前端未涉及后端以及数据库,所以不存在SQL注入、越权、密码爆破等核心安全隐患,经前端基础安全排查,未发现敏感信息泄露及XSS(跨站脚本攻击)风险。
3.5 自动化测试
3.5.1登陆页面自动化
from playwright.sync_api import sync_playwright import time import os SCREENSHOT_DIR = 'screenshots' if not os.path.exists(SCREENSHOT_DIR): os.makedirs(SCREENSHOT_DIR) def test_login_success(): """测试登录成功场景""" print("\n" + "="*60) print("测试场景:登录成功") print("="*60) with sync_playwright() as p: browser = p.chromium.launch(headless=False, slow_mo=500) page = browser.new_page() try: # 访问登录页面 page.goto('http://49.235.61.184:8080/user/login?redirect=%2Fhome') page.wait_for_load_state('networkidle') # 输入正确的用户名和密码 print("输入正确的用户名和密码...") page.locator('input[placeholder*="请输入"]').first.fill('LAY') page.locator('input[placeholder*="请输入"]').nth(1).fill('123456') # 点击登录按钮 page.locator('text=登 录').click() # 等待页面跳转 time.sleep(3) # 验证登录是否成功 if page.url == 'http://49.235.61.184:8080/home': print("✓ 登录成功!") page.screenshot(path=f'{SCREENSHOT_DIR}/01_login_success.png') else: print("✗ 登录失败,页面URL: " + page.url) page.screenshot(path=f'{SCREENSHOT_DIR}/01_login_failed.png') except Exception as e: print(f"✗ 测试过程中发生错误: {e}") page.screenshot(path=f'{SCREENSHOT_DIR}/01_login_error.png') finally: browser.close() def test_login_failed_wrong_credentials(): """测试登录失败场景:错误的用户名或密码""" print("\n" + "="*60) print("测试场景:错误的用户名或密码") print("="*60) with sync_playwright() as p: browser = p.chromium.launch(headless=False, slow_mo=500) page = browser.new_page() try: # 访问登录页面 page.goto('http://49.235.61.184:8080/user/login?redirect=%2Fhome') page.wait_for_load_state('networkidle') # 输入错误的用户名和密码 print("输入错误的用户名和密码...") page.locator('input[placeholder*="请输入"]').first.fill('wrong_user') page.locator('input[placeholder*="请输入"]').nth(1).fill('wrong_password') # 点击登录按钮 page.locator('text=登 录').click() # 等待错误提示出现 time.sleep(1) # 检查错误提示 error_locator = page.get_by_text("错误", exact=False) if error_locator.count() > 0: error_text = error_locator.first.text_content() print(f"✓ 检测到错误提示: {error_text}") page.screenshot(path=f'{SCREENSHOT_DIR}/02_wrong_credentials.png') else: print("✗ 未检测到预期的错误提示") page.screenshot(path=f'{SCREENSHOT_DIR}/02_no_error_message.png') except Exception as e: print(f"✗ 测试过程中发生错误: {e}") page.screenshot(path=f'{SCREENSHOT_DIR}/02_error.png') finally: browser.close() def test_login_failed_empty_username(): """测试登录失败场景:用户名为空""" print("\n" + "="*60) print("测试场景:用户名为空") print("="*60) with sync_playwright() as p: browser = p.chromium.launch(headless=False, slow_mo=500) page = browser.new_page() try: # 访问登录页面 page.goto('http://49.235.61.184:8080/user/login?redirect=%2Fhome') page.wait_for_load_state('networkidle') # 只输入密码,用户名留空 print("用户名留空,只输入密码...") page.locator('input[placeholder*="请输入"]').first.fill('') # 空用户名 page.locator('input[placeholder*="请输入"]').nth(1).fill('123456') # 点击登录按钮 page.locator('text=登 录').click() # 等待错误提示出现 time.sleep(1) # 检查错误提示(用户名必填) required_locator = page.get_by_text("必填", exact=False) username_error = page.get_by_text("用户名", exact=False) if required_locator.count() > 0 or username_error.count() > 0: error_text = "" if required_locator.count() > 0: error_text += required_locator.first.text_content() if username_error.count() > 0: error_text += " " + username_error.first.text_content() print(f"✓ 检测到必填提示: {error_text.strip()}") page.screenshot(path=f'{SCREENSHOT_DIR}/03_empty_username.png') else: print("✗ 未检测到预期的必填提示") page.screenshot(path=f'{SCREENSHOT_DIR}/03_no_required_message.png') except Exception as e: print(f"✗ 测试过程中发生错误: {e}") page.screenshot(path=f'{SCREENSHOT_DIR}/03_error.png') finally: browser.close() def test_login_failed_empty_password(): """测试登录失败场景:密码为空""" print("\n" + "="*60) print("测试场景:密码为空") print("="*60) with sync_playwright() as p: browser = p.chromium.launch(headless=False, slow_mo=500) page = browser.new_page() try: # 访问登录页面 page.goto('http://49.235.61.184:8080/user/login?redirect=%2Fhome') page.wait_for_load_state('networkidle') # 只输入用户名,密码留空 print("输入用户名,密码留空...") page.locator('input[placeholder*="请输入"]').first.fill('LAY') page.locator('input[placeholder*="请输入"]').nth(1).fill('') # 空密码 # 点击登录按钮 page.locator('text=登 录').click() # 等待错误提示出现 time.sleep(1) # 检查错误提示(密码必填) required_locator = page.get_by_text("必填", exact=False) password_error = page.get_by_text("密码", exact=False) if required_locator.count() > 0 or password_error.count() > 0: error_text = "" if required_locator.count() > 0: error_text += required_locator.first.text_content() if password_error.count() > 0: error_text += " " + password_error.first.text_content() print(f"✓ 检测到必填提示: {error_text.strip()}") page.screenshot(path=f'{SCREENSHOT_DIR}/04_empty_password.png') else: print("✗ 未检测到预期的必填提示") page.screenshot(path=f'{SCREENSHOT_DIR}/04_no_required_message.png') except Exception as e: print(f"✗ 测试过程中发生错误: {e}") page.screenshot(path=f'{SCREENSHOT_DIR}/04_error.png') finally: browser.close() if __name__ == '__main__': print("Playwright 自动化测试 - 登录功能测试套件") # 执行所有测试场景 test_login_success() test_login_failed_wrong_credentials() test_login_failed_empty_username() test_login_failed_empty_password() print("\n" + "="*60) print("所有测试场景已执行完毕!") print("="*60)3.5.2界面自动化
from playwright.sync_api import sync_playwright import time import os import random import string # 确保截图目录存在 SCREENSHOT_DIR = 'register_screenshots' if not os.path.exists(SCREENSHOT_DIR): os.makedirs(SCREENSHOT_DIR) # 登录页面URL LOGIN_URL = 'http://49.235.61.184:8080/user/login?redirect=%2Fhome' # 全局变量:用于场景6生成的随机账号 generated_account = "" # 测试统计 test_results = {"passed": 0, "failed": 0} def click_register_link(page): """点击注册账户链接进入注册页面""" try: register_link = page.locator("a:has-text('注册账户')") if register_link.count() > 0: register_link.click() page.wait_for_load_state('networkidle') time.sleep(1) return True else: print("✗ 未找到注册账户链接") return False except Exception as e: print(f"✗ 点击注册链接失败: {e}") return False def test_register_page_load(): """场景1:注册页面加载""" global test_results print("\n" + "="*60) print("场景1:注册页面加载") print("="*60) with sync_playwright() as p: browser = p.chromium.launch(headless=False, slow_mo=500) page = browser.new_page() try: # 访问登录页面 print("1. 访问登录页面...") page.goto(LOGIN_URL) page.wait_for_load_state('networkidle') # 点击注册账户链接 print("2. 点击注册账户链接...") if not click_register_link(page): page.screenshot(path=f'{SCREENSHOT_DIR}/01_register_page_fail.png') test_results["failed"] += 1 return # 验证姓名输入框是否存在 print("3. 验证姓名输入框是否存在...") name_input = page.locator("input[placeholder='用户名']") if name_input.count() > 0: print("✓ 姓名输入框存在") page.screenshot(path=f'{SCREENSHOT_DIR}/01_register_page.png') test_results["passed"] += 1 else: print("✗ 姓名输入框不存在") page.screenshot(path=f'{SCREENSHOT_DIR}/01_register_page_fail.png') test_results["failed"] += 1 except Exception as e: print(f"✗ 测试过程中发生错误: {e}") page.screenshot(path=f'{SCREENSHOT_DIR}/01_register_page_error.png') test_results["failed"] += 1 finally: browser.close() def test_password_too_short(): """场景2:密码少于6位校验""" global test_results print("\n" + "="*60) print("场景2:密码少于6位校验") print("="*60) with sync_playwright() as p: browser = p.chromium.launch(headless=False, slow_mo=500) page = browser.new_page() try: # 访问登录页面并进入注册页 print("1. 访问登录页面...") page.goto(LOGIN_URL) page.wait_for_load_state('networkidle') print("2. 点击注册账户链接进入注册页...") if not click_register_link(page): page.screenshot(path=f'{SCREENSHOT_DIR}/02_password_too_short_fail.png') test_results["failed"] += 1 return # 填写注册信息(随机生成少于6位的密码) short_password = ''.join(random.choices(string.ascii_letters + string.digits, k=random.randint(1, 5))) print(f"3. 填写注册信息(随机生成{len(short_password)}位密码:{short_password})...") page.locator("input[placeholder='用户名']").fill("测试用户A") page.locator("input[placeholder='请输入登录账号']").fill("testshort") page.locator("input[placeholder='密码']").first.fill(short_password) page.locator("input[placeholder='再次输入密码']").fill(short_password) # 点击注册按钮 print("4. 点击注册账户按钮...") page.locator("button:has-text('注册账户')").click() time.sleep(1) # 验证错误提示 print("5. 验证密码至少6位错误提示...") error_locator = page.get_by_text("密码至少6位", exact=False) if error_locator.count() > 0: print("✓ 检测到密码至少6位的错误提示") page.screenshot(path=f'{SCREENSHOT_DIR}/02_password_too_short.png') test_results["passed"] += 1 else: print("✗ 未检测到密码至少6位的错误提示") page.screenshot(path=f'{SCREENSHOT_DIR}/02_password_too_short_fail.png') test_results["failed"] += 1 except Exception as e: print(f"✗ 测试过程中发生错误: {e}") page.screenshot(path=f'{SCREENSHOT_DIR}/02_password_too_short_error.png') test_results["failed"] += 1 finally: browser.close() def test_password_mismatch(): """场景3:两次密码不一致校验""" global test_results print("\n" + "="*60) print("场景3:两次密码不一致校验") print("="*60) with sync_playwright() as p: browser = p.chromium.launch(headless=False, slow_mo=500) page = browser.new_page() try: # 访问登录页面并进入注册页 print("1. 访问登录页面...") page.goto(LOGIN_URL) page.wait_for_load_state('networkidle') print("2. 点击注册账户链接进入注册页...") if not click_register_link(page): page.screenshot(path=f'{SCREENSHOT_DIR}/03_password_mismatch_fail.png') test_results["failed"] += 1 return # 填写注册信息(两次密码不一致) print("3. 填写注册信息(两次密码不一致)...") page.locator("input[placeholder='用户名']").fill("测试用户B") page.locator("input[placeholder='请输入登录账号']").fill("testmismatch") page.locator("input[placeholder='密码']").first.fill("123456") page.locator("input[placeholder='再次输入密码']").fill("654321") # 点击注册按钮 print("4. 点击注册账户按钮...") page.locator("button:has-text('注册账户')").click() time.sleep(1) # 验证错误提示 print("5. 验证两次密码不一致错误提示...") error_locator = page.get_by_text("不一致", exact=False) if error_locator.count() > 0: print("✓ 检测到两次密码不一致的错误提示") page.screenshot(path=f'{SCREENSHOT_DIR}/03_password_mismatch.png') test_results["passed"] += 1 else: print("✗ 未检测到两次密码不一致的错误提示") page.screenshot(path=f'{SCREENSHOT_DIR}/03_password_mismatch_fail.png') test_results["failed"] += 1 except Exception as e: print(f"✗ 测试过程中发生错误: {e}") page.screenshot(path=f'{SCREENSHOT_DIR}/03_password_mismatch_error.png') test_results["failed"] += 1 finally: browser.close() def test_required_fields(): """场景4:必填项校验(所有字段为空)""" global test_results print("\n" + "="*60) print("场景4:必填项校验(所有字段为空)") print("="*60) with sync_playwright() as p: browser = p.chromium.launch(headless=False, slow_mo=500) page = browser.new_page() try: # 访问登录页面并进入注册页 print("1. 访问登录页面...") page.goto(LOGIN_URL) page.wait_for_load_state('networkidle') print("2. 点击注册账户链接进入注册页...") if not click_register_link(page): page.screenshot(path=f'{SCREENSHOT_DIR}/04_required_fields_fail.png') test_results["failed"] += 1 return # 所有字段留空,直接点击注册按钮 print("3. 所有字段留空,点击注册账户按钮...") page.locator("button:has-text('注册账户')").click() time.sleep(1) # 验证必填项提示 print("4. 验证必填项错误提示...") # 检测各种错误提示:必填、不能为空、请再次输入 required_count = page.get_by_text("必填", exact=False).count() empty_count = page.get_by_text("不能为空", exact=False).count() reenter_count = page.get_by_text("请再次输入", exact=False).count() total_errors = required_count + empty_count + reenter_count print(f"检测到必填提示数量: 必填={required_count}, 不能为空={empty_count}, 请再次输入={reenter_count}, 总计={total_errors}") if total_errors >= 4: print("✓ 所有必填项提示都已显示") page.screenshot(path=f'{SCREENSHOT_DIR}/04_required_fields.png') test_results["passed"] += 1 else: print(f"✗ 必填项提示不完整,期望至少4个,实际检测到{total_errors}个") page.screenshot(path=f'{SCREENSHOT_DIR}/04_required_fields_fail.png') test_results["failed"] += 1 except Exception as e: print(f"✗ 测试过程中发生错误: {e}") page.screenshot(path=f'{SCREENSHOT_DIR}/04_required_fields_error.png') test_results["failed"] += 1 finally: browser.close() def test_account_exists(): """场景5:账号已存在校验""" global test_results print("\n" + "="*60) print("场景5:账号已存在校验") print("="*60) with sync_playwright() as p: browser = p.chromium.launch(headless=False, slow_mo=500) page = browser.new_page() try: # 第一步:先注册一个账号 print("第一步:先注册一个账号...") page.goto(LOGIN_URL) page.wait_for_load_state('networkidle') if not click_register_link(page): page.screenshot(path=f'{SCREENSHOT_DIR}/05_first_register_fail.png') test_results["failed"] += 1 return print("填写注册信息...") page.locator("input[placeholder='用户名']").fill("已存在测试") page.locator("input[placeholder='请输入登录账号']").fill("testexist001") page.locator("input[placeholder='密码']").first.fill("123456") page.locator("input[placeholder='再次输入密码']").fill("123456") print("点击注册账户按钮...") page.locator("button:has-text('注册账户')").click() time.sleep(2) page.screenshot(path=f'{SCREENSHOT_DIR}/05_first_register.png') # 第二步:用同一个账号再次注册 print("\n第二步:用同一个账号再次注册...") page.goto(LOGIN_URL) page.wait_for_load_state('networkidle') if not click_register_link(page): page.screenshot(path=f'{SCREENSHOT_DIR}/06_account_exists_fail.png') test_results["failed"] += 1 return print("填写重复账号信息...") page.locator("input[placeholder='用户名']").fill("已存在测试2") page.locator("input[placeholder='请输入登录账号']").fill("testexist001") page.locator("input[placeholder='密码']").first.fill("123456") page.locator("input[placeholder='再次输入密码']").fill("123456") print("点击注册账户按钮...") page.locator("button:has-text('注册账户')").click() time.sleep(1) # 验证账号已存在提示 print("验证账号已存在错误提示...") error_locator = page.get_by_text("账号已存在", exact=False) if error_locator.count() > 0: print("✓ 检测到账号已存在的错误提示") page.screenshot(path=f'{SCREENSHOT_DIR}/06_account_exists.png') test_results["passed"] += 1 else: print("✗ 未检测到账号已存在的错误提示") page.screenshot(path=f'{SCREENSHOT_DIR}/06_account_exists_fail.png') test_results["failed"] += 1 except Exception as e: print(f"✗ 测试过程中发生错误: {e}") page.screenshot(path=f'{SCREENSHOT_DIR}/06_account_exists_error.png') test_results["failed"] += 1 finally: browser.close() def test_register_success(): """场景6:成功注册新账号""" global test_results, generated_account print("\n" + "="*60) print("场景6:成功注册新账号") print("="*60) with sync_playwright() as p: browser = p.chromium.launch(headless=False, slow_mo=500) page = browser.new_page() try: # 生成随机账号 timestamp = int(time.time()) generated_account = f"testuser_{timestamp}" print(f"生成随机账号: {generated_account}") # 访问登录页面并进入注册页 print("1. 访问登录页面...") page.goto(LOGIN_URL) page.wait_for_load_state('networkidle') print("2. 点击注册账户链接进入注册页...") if not click_register_link(page): page.screenshot(path=f'{SCREENSHOT_DIR}/07_register_success_fail.png') test_results["failed"] += 1 return # 填写注册信息 print("3. 填写注册信息...") page.locator("input[placeholder='用户名']").fill("自动化测试") page.locator("input[placeholder='请输入登录账号']").fill(generated_account) page.locator("input[placeholder='密码']").first.fill("123456") page.locator("input[placeholder='再次输入密码']").fill("123456") # 点击注册按钮 print("4. 点击注册账户按钮...") page.locator("button:has-text('注册账户')").click() time.sleep(2) # 验证注册成功(跳转到登录页) print("5. 验证注册成功...") if "login" in page.url.lower(): print(f"✓ 注册成功!生成的账号: {generated_account}") page.screenshot(path=f'{SCREENSHOT_DIR}/07_register_success.png') test_results["passed"] += 1 else: print(f"✗ 注册失败,当前URL: {page.url}") page.screenshot(path=f'{SCREENSHOT_DIR}/07_register_success_fail.png') test_results["failed"] += 1 except Exception as e: print(f"✗ 测试过程中发生错误: {e}") page.screenshot(path=f'{SCREENSHOT_DIR}/07_register_success_error.png') test_results["failed"] += 1 finally: browser.close() def test_register_then_login(): """场景7:注册成功后登录验证""" global test_results, generated_account print("\n" + "="*60) print("场景7:注册成功后登录验证") print("="*60) if not generated_account: print("✗ 未找到生成的账号,请先运行场景6") test_results["failed"] += 1 return with sync_playwright() as p: browser = p.chromium.launch(headless=False, slow_mo=500) page = browser.new_page() try: # 访问登录页面 print(f"1. 访问登录页面,使用账号: {generated_account}") page.goto(LOGIN_URL) page.wait_for_load_state('networkidle') # 输入账号和密码 print("2. 输入账号和密码...") page.locator('input[placeholder*="请输入"]').first.fill(generated_account) page.locator('input[placeholder*="请输入"]').nth(1).fill("123456") # 点击登录按钮 print("3. 点击登录按钮...") page.locator('text=登 录').click() time.sleep(2) # 验证登录成功(页面出现上午好或下午好) print("4. 验证登录成功...") greeting_locator = page.get_by_text("上午好", exact=False) if greeting_locator.count() == 0: greeting_locator = page.get_by_text("下午好", exact=False) if greeting_locator.count() > 0: print("✓ 登录成功!") page.screenshot(path=f'{SCREENSHOT_DIR}/08_login_success.png') test_results["passed"] += 1 else: print("✗ 未检测到上午好或下午好的问候语") page.screenshot(path=f'{SCREENSHOT_DIR}/08_login_success_fail.png') test_results["failed"] += 1 except Exception as e: print(f"✗ 测试过程中发生错误: {e}") page.screenshot(path=f'{SCREENSHOT_DIR}/08_login_success_error.png') test_results["failed"] += 1 finally: browser.close() def test_back_to_login(): """场景8:返回登录链接测试""" global test_results print("\n" + "="*60) print("场景8:返回登录链接测试") print("="*60) with sync_playwright() as p: browser = p.chromium.launch(headless=False, slow_mo=500) page = browser.new_page() try: # 访问登录页面并进入注册页 print("1. 访问登录页面...") page.goto(LOGIN_URL) page.wait_for_load_state('networkidle') print("2. 点击注册账户链接进入注册页...") if not click_register_link(page): page.screenshot(path=f'{SCREENSHOT_DIR}/09_back_to_login_fail.png') test_results["failed"] += 1 return # 点击返回登录链接 print("3. 点击返回登录链接...") back_link = page.locator("a:has-text('返回登录')") if back_link.count() > 0: back_link.click() page.wait_for_load_state('networkidle') time.sleep(1) # 验证是否跳转回登录页面 print("4. 验证是否跳转回登录页面...") if "login" in page.url.lower(): print("✓ 成功跳转回登录页面") page.screenshot(path=f'{SCREENSHOT_DIR}/09_back_to_login.png') test_results["passed"] += 1 else: print(f"✗ 未跳转回登录页面,当前URL: {page.url}") page.screenshot(path=f'{SCREENSHOT_DIR}/09_back_to_login_fail.png') test_results["failed"] += 1 else: print("✗ 未找到返回登录链接") page.screenshot(path=f'{SCREENSHOT_DIR}/09_back_to_login_fail.png') test_results["failed"] += 1 except Exception as e: print(f"✗ 测试过程中发生错误: {e}") page.screenshot(path=f'{SCREENSHOT_DIR}/09_back_to_login_error.png') test_results["failed"] += 1 finally: browser.close() def print_summary(): """打印测试总结""" print("\n" + "="*60) print("测试总结") print("="*60) total = test_results["passed"] + test_results["failed"] print(f"共测试 {total} 个场景") print(f"通过: {test_results['passed']} 个") print(f"失败: {test_results['failed']} 个") print("="*60) if __name__ == "__main__": # 执行所有测试场景 test_register_page_load() test_password_too_short() test_password_mismatch() test_required_fields() test_account_exists() test_register_success() test_register_then_login() test_back_to_login() # 打印测试总结 print_summary()3.5.3兼容性测试
from playwright.sync_api import sync_playwright import time from datetime import datetime # 要测试的浏览器列表(添加Edge浏览器) browsers_to_test = ["chromium", "firefox", "webkit", "edge"] def test_login(browser_name): print(f"\n🚀 开始测试: {browser_name}") with sync_playwright() as p: # 根据浏览器名称启动对应的浏览器 if browser_name == "chromium": browser = p.chromium.launch(headless=False) elif browser_name == "firefox": # 设置火狐浏览器语言为中文,解决英文版识别问题 browser = p.firefox.launch(headless=False, args=["--lang=zh-CN"]) elif browser_name == "webkit": browser = p.webkit.launch(headless=False) elif browser_name == "edge": # 使用Chromium通道启动Microsoft Edge浏览器 browser = p.chromium.launch(headless=False, channel="msedge") else: print(f"❌ 不支持的浏览器: {browser_name}") return False page = browser.new_page() try: # 1. 访问登录页 page.goto("http://49.235.61.184:8080/user/login?redirect=%2Fhome", timeout=30000) page.wait_for_load_state('networkidle') print(f"✅ 访问登录页成功") page.screenshot(path=f"screenshots/compatibility/{browser_name}_01_login_page.png") # 2. 输入账号密码(支持中英文placeholder,包括"Please enter") # 使用nth()区分输入框:第1个是用户名,第2个是密码 all_inputs = page.locator('input[placeholder*="请输入"], input[placeholder*="username"], input[placeholder*="account"], input[placeholder*="密码"], input[placeholder*="password"], input[placeholder*="Please enter"]') all_inputs.nth(0).fill('LAY') all_inputs.nth(1).fill('123456') print(f"✅ 输入账号密码完成") page.screenshot(path=f"screenshots/compatibility/{browser_name}_02_after_fill.png") # 3. 点击登录按钮(支持中英文按钮文本) login_button = page.locator('text=登 录').first if page.locator('text=登 录').count() > 0 else page.locator('text=登录').first if page.locator('text=登录').count() > 0 else page.locator('text=Login').first login_button.click() print(f"✅ 点击登录按钮") # 4. 等待登录完成(等待"下午好"出现) page.wait_for_timeout(3000) page.screenshot(path=f"screenshots/compatibility/{browser_name}_03_after_login.png") # 5. 验证登录成功(支持中英文欢迎语) body_text = page.text_content("body") chinese_greetings = ["下午好", "上午好", "您好"] english_greetings = ["Good morning", "Good afternoon", "Hello", "Welcome"] # 检测欢迎语 found_greeting = False detected_greeting = "" for greeting in chinese_greetings: if greeting in body_text: found_greeting = True detected_greeting = greeting break if not found_greeting: for greeting in english_greetings: if greeting in body_text: found_greeting = True detected_greeting = greeting break if found_greeting: print(f"✅ {browser_name} 登录成功!检测到欢迎语: {detected_greeting}") # 验证欢迎语是否实时(根据当前时间判断) current_hour = datetime.now().hour expected_greeting_type = "上午" if current_hour < 12 else "下午" if "上午好" in body_text or "Good morning" in body_text: actual_type = "上午" elif "下午好" in body_text or "Good afternoon" in body_text: actual_type = "下午" else: actual_type = "未知" if actual_type == expected_greeting_type: print(f"✅ {browser_name} 欢迎语实时性验证通过!当前时间{current_hour}:00,显示{actual_type}好") else: print(f"⚠️ {browser_name} 欢迎语可能不是实时的!当前时间{current_hour}:00,期望{expected_greeting_type}好,实际显示{actual_type}好") else: print(f"❌ {browser_name} 登录失败,未找到欢迎语") return False # 6. 验证首页统计数据显示(支持中英文) chinese_stats = ["问卷数", "考试数", "用户数"] english_stats = ["Questionnaire", "Exam", "User"] chinese_count = sum(1 for stat in chinese_stats if stat in body_text) english_count = sum(1 for stat in english_stats if stat in body_text) if chinese_count >= 2 or english_count >= 2: print(f"✅ {browser_name} 统计数据显示正常") else: print(f"⚠️ {browser_name} 统计数据未显示") print(f"✅ {browser_name} 兼容性测试通过 🎉") return True except Exception as e: print(f"❌ {browser_name} 测试报错: {e}") page.screenshot(path=f"screenshots/compatibility/{browser_name}_ERROR.png") return False finally: browser.close() # 运行所有浏览器测试 if __name__ == "__main__": print("=" * 50) print("🚀 开始多浏览器兼容性测试") print("=" * 50) results = {} for browser in browsers_to_test: results[browser] = test_login(browser) # 打印汇总结果 print("\n" + "=" * 50) print("📊 兼容性测试汇总") print("=" * 50) for browser, passed in results.items(): if passed: print(f" {browser}: ✅ 通过") else: print(f" {browser}: ❌ 失败") total = len(results) passed_count = sum(results.values()) print(f"\n共测试 {total} 个浏览器,通过 {passed_count} 个,失败 {total - passed_count} 个")