卷王问卷考试系统 -测试报告

卷王问卷考试系统 -测试报告

一.项目背景

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} 个")
3.5.4自动化测试报告