#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ 首页按钮点击与跳转审查自动化测试 (TDD) 验证首页所有按钮(PC 端与移动端)均准确跳转到对应的业务位置或锚点 """ import os import re import unittest BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) class HomepageButtonLinksTest(unittest.TestCase): def setUp(self): self.pc_home_path = os.path.join(BASE_DIR, 'addons', 'official', 'view', 'web', 'official_home', 'index.html') self.mobile_home_path = os.path.join(BASE_DIR, 'addons', 'official', 'view', 'web', 'official_home', 'index_e.html') self.pc_nav_path = os.path.join(BASE_DIR, 'addons', 'official', 'view', 'web', 'official_common', 'pc', 'nav.html') self.css_path = os.path.join(BASE_DIR, 'public', 'assets', 'addons', 'official', 'css', 'modern_nhc.css') with open(self.pc_home_path, 'r', encoding='utf-8') as f: self.pc_html = f.read() with open(self.mobile_home_path, 'r', encoding='utf-8') as f: self.mobile_html = f.read() with open(self.pc_nav_path, 'r', encoding='utf-8') as f: self.pc_nav = f.read() with open(self.css_path, 'r', encoding='utf-8') as f: self.css = f.read() def test_01_pc_hero_carousel_buttons(self): """PC 首页首屏轮播图所有按钮跳转必须精准""" # 幻灯片 1:预约架构师评估 与 浏览成熟产品 self.assertIn('#contact', self.pc_html, "首屏应包含直达联系模块的锚点跳转") self.assertIn('#products', self.pc_html, "首屏应包含直达产品矩阵的锚点跳转") # 幻灯片 2:软件开发能力 与 标杆案例 self.assertTrue( "official_product/list" in self.pc_html and ":pid'=>19" in self.pc_html, "幻灯片2必须准确跳转到服务页 (:pid=>19)" ) self.assertTrue( "official_case_show/list" in self.pc_html and ":pid'=>14" in self.pc_html, "幻灯片2必须准确跳转到案例页 (:pid=>14)" ) # 幻灯片 4:申请演示 - 严禁粗糙跳到没有演示功能的 #products # 必须跳转到产品页演示沙箱 demo-sandbox 或联系预约 self.assertFalse( re.search(r']*>(?:(?!)[\s\S])*?申请(?:全功能在线)?演示', self.pc_html), "申请演示严禁跳往 #products,必须精准跳转演示沙箱或预约页面" ) self.assertTrue( "demo-sandbox" in self.pc_html or "official_online_message/list" in self.pc_html, "申请在线演示必须链接到 demo-sandbox 或联系预约" ) def test_02_pc_service_section_buttons(self): """PC 首页服务板块跳转必须准确一致""" # 核心服务一与二必须跳转服务页 self.assertTrue( "official_product/list" in self.pc_html and ":pid'=>19" in self.pc_html, "软件开发服务卡片必须跳转到服务页" ) # 核心服务三:如果是“探索智能体开发方案”,跳转到服务页;如果是“案例”,必须跳案例页,文案与链接不能精神分裂 if "探索智能体落地案例" in self.pc_html: # 如果文案是案例,则链接必须是案例页 self.assertTrue( "official_case_show/list" in self.pc_html, "探索智能体落地案例必须指向案例页" ) def test_03_pc_product_section_buttons(self): """PC 首页四大成熟商用系统按钮必须跳转到对应位置""" # 收银「申请演示」必须跳往产品页的演示沙箱 #demo-sandbox 或联系页 self.assertTrue( re.search(r'href="\{:addon_url\(\'official/web\.official_product/list\',\[\':pid\'=>22,\':sid\'=>22\]\)\}#demo-sandbox"[^>]*>[\s\S]*?申请演示', self.pc_html) or ("demo-sandbox" in self.pc_html and "申请演示" in self.pc_html), "收银系统【申请演示】必须精准跳转到产品独立页演示沙箱" ) # SaaS版本「咨询开通」应指向联系预约,避免承诺点击后直接开通。 self.assertTrue( re.search(r']*href="\{:addon_url\(\'official/web\.official_online_message/list\',[^\n]*?\)\}"[^>]*>\s*咨询开通', self.pc_html), "SaaS版本【咨询开通】必须跳转到联系留言页" ) def test_04_pc_case_cards_clickable(self): """PC 首页案例卡片必须具备可点击跳转到案例页的入口""" # 每个案例卡片应包含查看详情链接或整卡可点击 case_links_count = len(re.findall(r'official_case_show/list', self.pc_html)) self.assertGreaterEqual(case_links_count, 3, "首页案例板块及卡片必须包含足够的案例页跳转链接") self.assertTrue("浏览案例" in self.pc_html or "浏览全部标杆案例" in self.pc_html, "首页案例板块必须包含案例跳转主按钮") def test_05_pc_process_and_cta_buttons(self): """PC 首页交付流程与底部 CTA 按钮跳转""" # 底部 CTA 必须有预约咨询和致电专线 self.assertTrue( "official_online_message/list" in self.pc_html and ":pid'=>18" in self.pc_html, "底部 CTA 必须准确跳转到联系留言独立页 (:pid=>18)" ) self.assertIn('tel:{:__config(\'site_mobile\',\'value\')}', self.pc_html, "底部 CTA 必须包含拨打电话链接") def test_06_nav_actions_button(self): """导航栏右上角行动按钮必须全局可用,不能是单页孤立锚点""" self.assertFalse( re.search(r']*>(?:(?!)[\s\S])*?申请(?:全系统)?演示', self.mobile_html), "移动端申请全系统演示严禁跳转 #products,必须跳转演示沙箱或联系预约" ) # 服务、产品、案例必须有链接或按钮跳转到独立页 self.assertTrue( "official_product/list" in self.mobile_html and ":pid'=>19" in self.mobile_html, "移动端服务板块必须有直达服务独立页的跳转链接" ) self.assertTrue( "official_product/list" in self.mobile_html and ":pid'=>22" in self.mobile_html, "移动端产品板块必须有直达产品独立页的跳转链接" ) self.assertTrue( "official_case_show/list" in self.mobile_html and ":pid'=>14" in self.mobile_html, "移动端案例板块必须有直达案例独立页的跳转链接" ) # 移动端底部 CTA 必须有在线咨询与致电 self.assertTrue( "official_online_message/list" in self.mobile_html or "tel:" in self.mobile_html, "移动端底部 CTA 必须具备有效联络跳转" ) def test_08_smooth_scroll_and_offset(self): """CSS 必须具备平滑滚动与避免 fixed 导航遮挡的 scroll-margin-top""" self.assertIn('scroll-behavior: smooth', self.css, "CSS 必须配置 scroll-behavior: smooth") self.assertIn('scroll-margin-top', self.css, "CSS 必须配置 scroll-margin-top 防止锚点被 fixed 导航遮挡") def test_09_button_text_conciseness(self): """验证所有冗长、累赘的按钮文本已被精简,符合现代专业大厂风范""" # 冗长文本清单 verbose_texts = [ "预约架构师技术初审", "致电技术专线", "预约架构师评估", "浏览成熟产品", "了解软件开发能力", "查阅标杆案例", "预约智能体方案研讨", "查看技术架构", "申请全功能在线演示", "咨询部署与报价", "查看案例复盘与实测数据", "浏览全部标杆案例", "查阅标准化研发流程与质量规范", "浏览全部技术动态", "申请在线系统演示", "查阅服务能力", "致电架构师专线", "申请在线演示沙箱", "申请商城演示", "申请收银演示", "申请进销存演示", "申请 SaaS 演示", "咨询公有云订阅方案", "预约私有化部署评估", "立即开通专属演示账号", "立即提交选型咨询", "致电产品专线", "预约架构师方案研讨", "致电案例咨询", "立即提交需求评估", ] # 读取全站待审查的模板内容 check_files = [ self.pc_home_path, self.mobile_home_path, self.pc_nav_path, os.path.join(BASE_DIR, 'addons', 'official', 'view', 'web', 'official_product', 'service_page.html'), os.path.join(BASE_DIR, 'addons', 'official', 'view', 'web', 'official_product', 'product_page.html'), os.path.join(BASE_DIR, 'addons', 'official', 'view', 'web', 'official_case_show', 'list.html'), os.path.join(BASE_DIR, 'addons', 'official', 'view', 'web', 'official_home', 'single.html'), os.path.join(BASE_DIR, 'addons', 'official', 'view', 'web', 'official_online_message', 'list.html'), ] for fpath in check_files: if not os.path.exists(fpath): continue with open(fpath, 'r', encoding='utf-8') as f: content = f.read() for v_text in verbose_texts: self.assertNotIn( f'{v_text}', content, f"文件 {os.path.basename(fpath)} 中仍包含未精简的冗长按钮文本: {v_text}" ) self.assertNotIn( f'>{v_text}<', content, f"文件 {os.path.basename(fpath)} 中仍包含未精简的冗长按钮文本: {v_text}" ) if __name__ == '__main__': unittest.main()