diff --git a/scripts/comprehensive_button_check.py b/scripts/comprehensive_button_check.py new file mode 100644 index 0000000..747447d --- /dev/null +++ b/scripts/comprehensive_button_check.py @@ -0,0 +1,134 @@ +#!/usr/bin/env python3 +""" +全面检查所有页面的按钮显示(忽略移动端菜单) +检查多个页面的 RippleButton 是否正常显示 +""" + +from playwright.sync_api import sync_playwright +import sys + +def check_page_buttons(page, url, page_name): + """检查指定页面的按钮""" + print(f"\n{'='*60}") + print(f"🔍 检查页面: {page_name}") + print(f"📍 URL: {url}") + print(f"{'='*60}") + + try: + page.goto(url, timeout=30000) + page.wait_for_load_state('networkidle') + + # 截图保存 + screenshot_name = page_name.replace('/', '-').replace(' ', '_') + screenshot_path = f'test-results/{screenshot_name}.png' + page.screenshot(path=screenshot_path, full_page=True) + print(f"📸 截图已保存: {screenshot_path}") + + # 查找所有可能的按钮(包括 a 标签和 button 标签) + all_buttons = page.locator('a, button').all() + + # 过滤出包含文本的按钮,并排除移动端菜单按钮 + buttons_with_text = [] + mobile_menu_buttons = ['首页', '服务', '产品', '新闻', '联系'] # 移动端菜单按钮 + + for button in all_buttons: + try: + text = button.inner_text().strip() + # 只关注短文本按钮,并排除移动端菜单 + if text and len(text) < 50 and text not in mobile_menu_buttons: + buttons_with_text.append({ + 'element': button, + 'text': text + }) + except: + pass + + print(f"\n📊 找到 {len(buttons_with_text)} 个按钮/链接(已排除移动端菜单)") + + # 检查每个按钮 + issues = [] + for btn_info in buttons_with_text: + button = btn_info['element'] + text = btn_info['text'] + + try: + is_visible = button.is_visible() + text_color = button.evaluate('el => window.getComputedStyle(el).color') + bg_color = button.evaluate('el => window.getComputedStyle(el).backgroundColor') + opacity = button.evaluate('el => window.getComputedStyle(el).opacity') + + # 检查文字是否可见(文字颜色不应与背景色相同) + if 'rgb(196, 30, 58)' in text_color and 'rgb(196, 30, 58)' in bg_color: + issue = f"❌ 按钮 '{text}': 红色文字 + 红色背景 (可能不可见)" + issues.append(issue) + print(f" {issue}") + elif float(opacity) < 0.1: + issue = f"❌ 按钮 '{text}': 透明度过低 ({opacity})" + issues.append(issue) + print(f" {issue}") + elif not is_visible: + issue = f"⚠️ 按钮 '{text}': 不可见" + issues.append(issue) + print(f" {issue}") + else: + print(f" ✅ 按钮 '{text}': 正常") + + except Exception as e: + print(f" ⚠️ 按钮 '{text}': 检查失败 - {e}") + + if issues: + print(f"\n⚠️ 发现 {len(issues)} 个问题:") + for issue in issues: + print(f" {issue}") + return False + else: + print(f"\n✅ 所有按钮正常") + return True + + except Exception as e: + print(f"\n❌ 页面检查失败: {e}") + return False + +def main(): + pages_to_check = [ + {"url": "http://localhost:3000/", "name": "首页"}, + {"url": "http://localhost:3000/services/software", "name": "软件开发服务"}, + {"url": "http://localhost:3000/services/data", "name": "数据分析服务"}, + {"url": "http://localhost:3000/products/erp", "name": "ERP产品"}, + {"url": "http://localhost:3000/products/crm", "name": "CRM产品"}, + {"url": "http://localhost:3000/solutions/manufacturing", "name": "制造业解决方案"}, + {"url": "http://localhost:3000/contact", "name": "联系我们"}, + ] + + with sync_playwright() as p: + browser = p.chromium.launch(headless=True) + page = browser.new_page() + + results = {} + for page_info in pages_to_check: + result = check_page_buttons(page, page_info['url'], page_info['name']) + results[page_info['name']] = result + + browser.close() + + # 总结 + print(f"\n{'='*60}") + print("📋 检查总结") + print(f"{'='*60}") + + all_passed = True + for page_name, passed in results.items(): + status = "✅ 通过" if passed else "❌ 失败" + print(f"{status} - {page_name}") + if not passed: + all_passed = False + + if all_passed: + print(f"\n🎉 所有页面检查通过!") + return 0 + else: + print(f"\n⚠️ 部分页面存在问题,请检查截图和日志。") + return 1 + +if __name__ == '__main__': + sys.exit(main()) diff --git a/scripts/verify_buttons.py b/scripts/verify_buttons.py new file mode 100644 index 0000000..95cd708 --- /dev/null +++ b/scripts/verify_buttons.py @@ -0,0 +1,93 @@ +#!/usr/bin/env python3 +""" +验证按钮显示修复效果 +检查软件开发服务页面的三个CTA按钮是否正常显示文字 +""" + +from playwright.sync_api import sync_playwright +import sys + +def verify_buttons(): + with sync_playwright() as p: + browser = p.chromium.launch(headless=True) + page = browser.new_page() + + try: + # 访问软件开发服务页面 + print("🔍 正在访问软件开发服务页面...") + page.goto('http://localhost:3000/services/software', timeout=30000) + page.wait_for_load_state('networkidle') + + # 截图保存 + screenshot_path = 'test-results/service-page-buttons.png' + page.screenshot(path=screenshot_path, full_page=True) + print(f"📸 页面截图已保存: {screenshot_path}") + + # 查找所有 RippleButton(通过文本内容识别) + buttons_to_check = [ + {"text": "预约演示", "expected": "outline variant with red text"}, + {"text": "免费咨询", "expected": "solid red background with white text"}, + {"text": "了解详情", "expected": "outline variant with red text"} + ] + + print("\n✅ 按钮验证结果:") + all_buttons_found = True + + for button_info in buttons_to_check: + try: + # 查找包含指定文本的按钮 + button = page.locator(f'a:has-text("{button_info["text"]}"), button:has-text("{button_info["text"]}")').first + + if button.count() > 0: + # 获取按钮的样式信息 + button_text = button.inner_text() + is_visible = button.is_visible() + + # 检查按钮是否有可见的文本 + text_color = button.evaluate('el => window.getComputedStyle(el).color') + bg_color = button.evaluate('el => window.getComputedStyle(el).backgroundColor') + + print(f"\n ✓ 按钮 '{button_text}':") + print(f" - 可见性: {'✅ 可见' if is_visible else '❌ 不可见'}") + print(f" - 文字颜色: {text_color}") + print(f" - 背景颜色: {bg_color}") + print(f" - 预期样式: {button_info['expected']}") + + # 检查文字是否可见(文字颜色不应与背景色相同) + if is_visible and button_text: + print(f" - 状态: ✅ 正常显示") + else: + print(f" - 状态: ❌ 可能存在问题") + all_buttons_found = False + else: + print(f"\n ❌ 未找到按钮: '{button_info['text']}'") + all_buttons_found = False + + except Exception as e: + print(f"\n ❌ 检查按钮 '{button_info['text']}' 时出错: {e}") + all_buttons_found = False + + # 额外检查:确保按钮文字不是透明的 + print("\n🔍 额外检查:按钮文字透明度...") + all_buttons = page.locator('a:has-text("预约演示"), a:has-text("免费咨询"), a:has-text("了解详情")').all() + + for button in all_buttons: + text = button.inner_text() + opacity = button.evaluate('el => window.getComputedStyle(el).opacity') + print(f" - '{text}' 透明度: {opacity}") + + if all_buttons_found: + print("\n🎉 验证成功!所有按钮都正常显示文字。") + return 0 + else: + print("\n⚠️ 部分按钮可能存在问题,请检查截图。") + return 1 + + except Exception as e: + print(f"\n❌ 验证过程中出错: {e}") + return 1 + finally: + browser.close() + +if __name__ == '__main__': + sys.exit(verify_buttons()) diff --git a/src/app/(marketing)/news/[slug]/NewsDetailClient.test.tsx b/src/app/(marketing)/news/[slug]/NewsDetailClient.test.tsx index 490c797..e3dac55 100644 --- a/src/app/(marketing)/news/[slug]/NewsDetailClient.test.tsx +++ b/src/app/(marketing)/news/[slug]/NewsDetailClient.test.tsx @@ -10,9 +10,11 @@ jest.mock('next/navigation', () => ({ })); jest.mock('next/link', () => { - return ({ children, href }: { children: React.ReactNode; href: string }) => { + const MockLink = ({ children, href }: { children: React.ReactNode; href: string }) => { return {children}; }; + MockLink.displayName = 'MockLink'; + return MockLink; }); jest.mock('framer-motion', () => ({ diff --git a/src/app/(marketing)/products/[id]/page.test.tsx b/src/app/(marketing)/products/[id]/page.test.tsx index feb0269..ac88a49 100644 --- a/src/app/(marketing)/products/[id]/page.test.tsx +++ b/src/app/(marketing)/products/[id]/page.test.tsx @@ -41,7 +41,7 @@ jest.mock('@/lib/constants', () => ({ // Mock ProductDetailClient 组件 jest.mock('./product-detail-client', () => ({ - ProductDetailClient: ({ productId }: any) => ( + ProductDetailClient: () => (
{COMPANY_INFO.slogan}
diff --git a/src/components/sections/hero-section-atoms.tsx b/src/components/sections/hero-section-atoms.tsx
index 3b61d43..a4858c9 100644
--- a/src/components/sections/hero-section-atoms.tsx
+++ b/src/components/sections/hero-section-atoms.tsx
@@ -59,8 +59,9 @@ export function HeroTitle(_props: HeroContentProps) {