diff --git a/README.md b/README.md index c8b23cd..339b93c 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,7 @@ - [x] 全站 dogfood 问题修复(2026-07-25):修复列表详情页导航、CMS 登录状态、服务详情页软 404 等 High 优先级问题;其中软 404 根因定位为 `(marketing)/loading.tsx` 形成的 Loading/Suspense 边界吞掉了动态路由 `notFound()` 抛出的 NEXT_NOT_FOUND 错误,导致未知 slug 返回 HTTP 200,已移除该 loading.tsx 并修复根 `not-found.tsx`;type-check / lint(0 errors,172 既有 warnings)/ test:unit(72 suites / 954 tests)/ 功能 E2E 140 条全部通过 - [x] dogfood 剩余问题验证与视觉基线更新(2026-07-26):浏览器实测确认主导航「产品/解决方案」下拉菜单 click/hover 均可正常展开,问题已随 `(marketing)/loading.tsx` 移除解决;同步修正 `e2e/nav-dropdown.spec.ts` 中断言文本(`睿新ERP管理系统` → `ERP 管理系统`、`行业方案` → `行业解决方案`);更新 desktop/tablet/mobile/webkit/firefox 全量视觉回归基线(105 张快照);type-check / lint(0 errors,172 既有 warnings)/ test:unit(72 suites / 954 tests)/ 下拉菜单 E2E 全部通过 - [x] 全量回归与 E2E 配置修复(2026-07-27):修复 `e2e/playwright.config.ts` 中 `storageState` 路径错误(由 `./e2e/storageState.json` 改为基于配置文件目录的绝对路径),该错误导致 firefox/webkit 全量 E2E 运行时无法读取 Cookie 偏好状态而全部失败;将 `e2e/p2-functional-e2e.spec.ts` 中「Footer 导航链接可点击」拆分为隐私政策、服务条款两个独立测试,并改用 `page.evaluate` 直接触发点击,避免 Firefox 中连续全页导航与 Playwright locator 评估的竞态超时;重新执行全量回归:type-check / lint(0 errors,172 既有 warnings)/ test:unit(72 suites / 954 tests)/ E2E 全量(631 passed / 8 skipped / 0 failed,含视觉回归、CMS 工作流)全部通过 +- [x] 联系表单 conversion 去重与首页 Hero 品牌标识补齐(2026-07-27):移除 `contact-content-v3.tsx` 中冗余的 `trackConversion('contact_form_submission')` 调用,改为 `trackContactForm(..., true)`,避免一次成功提交在 GA4 中被计为两次转化;同步更新 `contact-content-v3.test.tsx` 中断言;在 `home-content-v14.tsx` 首页 Hero 主标题上方增加 Logo + 公司中文名 + NOVALON 英文品牌标识,补齐截图中缺失的品牌信息;更新首页相关 desktop/tablet/mobile 视觉回归基线;type-check / lint(0 errors,172 既有 warnings)/ 相关 unit 测试全部通过 ## 技术栈 diff --git a/e2e/visual-snapshots/visual-chromium-desktop/visual-regression.spec.ts/home-fullpage-visual-chromium-desktop.png b/e2e/visual-snapshots/visual-chromium-desktop/visual-regression.spec.ts/home-fullpage-visual-chromium-desktop.png index 39be905..38adf39 100644 Binary files a/e2e/visual-snapshots/visual-chromium-desktop/visual-regression.spec.ts/home-fullpage-visual-chromium-desktop.png and b/e2e/visual-snapshots/visual-chromium-desktop/visual-regression.spec.ts/home-fullpage-visual-chromium-desktop.png differ diff --git a/e2e/visual-snapshots/visual-chromium-desktop/visual-regression.spec.ts/theme-dark-main-visual-chromium-desktop.png b/e2e/visual-snapshots/visual-chromium-desktop/visual-regression.spec.ts/theme-dark-main-visual-chromium-desktop.png index d3d5279..598aab3 100644 Binary files a/e2e/visual-snapshots/visual-chromium-desktop/visual-regression.spec.ts/theme-dark-main-visual-chromium-desktop.png and b/e2e/visual-snapshots/visual-chromium-desktop/visual-regression.spec.ts/theme-dark-main-visual-chromium-desktop.png differ diff --git a/e2e/visual-snapshots/visual-chromium-desktop/visual-regression.spec.ts/theme-light-main-visual-chromium-desktop.png b/e2e/visual-snapshots/visual-chromium-desktop/visual-regression.spec.ts/theme-light-main-visual-chromium-desktop.png index d3d5279..598aab3 100644 Binary files a/e2e/visual-snapshots/visual-chromium-desktop/visual-regression.spec.ts/theme-light-main-visual-chromium-desktop.png and b/e2e/visual-snapshots/visual-chromium-desktop/visual-regression.spec.ts/theme-light-main-visual-chromium-desktop.png differ diff --git a/e2e/visual-snapshots/visual-chromium-mobile/visual-regression.spec.ts/home-fullpage-visual-chromium-mobile.png b/e2e/visual-snapshots/visual-chromium-mobile/visual-regression.spec.ts/home-fullpage-visual-chromium-mobile.png index 1aa0ba8..f84cd0b 100644 Binary files a/e2e/visual-snapshots/visual-chromium-mobile/visual-regression.spec.ts/home-fullpage-visual-chromium-mobile.png and b/e2e/visual-snapshots/visual-chromium-mobile/visual-regression.spec.ts/home-fullpage-visual-chromium-mobile.png differ diff --git a/e2e/visual-snapshots/visual-chromium-mobile/visual-regression.spec.ts/theme-dark-main-visual-chromium-mobile.png b/e2e/visual-snapshots/visual-chromium-mobile/visual-regression.spec.ts/theme-dark-main-visual-chromium-mobile.png index 2fd98f8..b961a5b 100644 Binary files a/e2e/visual-snapshots/visual-chromium-mobile/visual-regression.spec.ts/theme-dark-main-visual-chromium-mobile.png and b/e2e/visual-snapshots/visual-chromium-mobile/visual-regression.spec.ts/theme-dark-main-visual-chromium-mobile.png differ diff --git a/e2e/visual-snapshots/visual-chromium-mobile/visual-regression.spec.ts/theme-light-main-visual-chromium-mobile.png b/e2e/visual-snapshots/visual-chromium-mobile/visual-regression.spec.ts/theme-light-main-visual-chromium-mobile.png index 2fd98f8..b961a5b 100644 Binary files a/e2e/visual-snapshots/visual-chromium-mobile/visual-regression.spec.ts/theme-light-main-visual-chromium-mobile.png and b/e2e/visual-snapshots/visual-chromium-mobile/visual-regression.spec.ts/theme-light-main-visual-chromium-mobile.png differ diff --git a/e2e/visual-snapshots/visual-chromium-tablet/visual-regression.spec.ts/home-fullpage-visual-chromium-tablet.png b/e2e/visual-snapshots/visual-chromium-tablet/visual-regression.spec.ts/home-fullpage-visual-chromium-tablet.png index 65e8f9f..f9a878c 100644 Binary files a/e2e/visual-snapshots/visual-chromium-tablet/visual-regression.spec.ts/home-fullpage-visual-chromium-tablet.png and b/e2e/visual-snapshots/visual-chromium-tablet/visual-regression.spec.ts/home-fullpage-visual-chromium-tablet.png differ diff --git a/e2e/visual-snapshots/visual-chromium-tablet/visual-regression.spec.ts/theme-dark-main-visual-chromium-tablet.png b/e2e/visual-snapshots/visual-chromium-tablet/visual-regression.spec.ts/theme-dark-main-visual-chromium-tablet.png index 02410cf..ac4ba8d 100644 Binary files a/e2e/visual-snapshots/visual-chromium-tablet/visual-regression.spec.ts/theme-dark-main-visual-chromium-tablet.png and b/e2e/visual-snapshots/visual-chromium-tablet/visual-regression.spec.ts/theme-dark-main-visual-chromium-tablet.png differ diff --git a/e2e/visual-snapshots/visual-chromium-tablet/visual-regression.spec.ts/theme-light-main-visual-chromium-tablet.png b/e2e/visual-snapshots/visual-chromium-tablet/visual-regression.spec.ts/theme-light-main-visual-chromium-tablet.png index 02410cf..ac4ba8d 100644 Binary files a/e2e/visual-snapshots/visual-chromium-tablet/visual-regression.spec.ts/theme-light-main-visual-chromium-tablet.png and b/e2e/visual-snapshots/visual-chromium-tablet/visual-regression.spec.ts/theme-light-main-visual-chromium-tablet.png differ diff --git a/e2e/visual-snapshots/visual-firefox-desktop/visual-regression.spec.ts/home-fullpage-visual-firefox-desktop.png b/e2e/visual-snapshots/visual-firefox-desktop/visual-regression.spec.ts/home-fullpage-visual-firefox-desktop.png index 4446c38..a8776f5 100644 Binary files a/e2e/visual-snapshots/visual-firefox-desktop/visual-regression.spec.ts/home-fullpage-visual-firefox-desktop.png and b/e2e/visual-snapshots/visual-firefox-desktop/visual-regression.spec.ts/home-fullpage-visual-firefox-desktop.png differ diff --git a/e2e/visual-snapshots/visual-firefox-desktop/visual-regression.spec.ts/theme-dark-main-visual-firefox-desktop.png b/e2e/visual-snapshots/visual-firefox-desktop/visual-regression.spec.ts/theme-dark-main-visual-firefox-desktop.png index 7dae458..c382d06 100644 Binary files a/e2e/visual-snapshots/visual-firefox-desktop/visual-regression.spec.ts/theme-dark-main-visual-firefox-desktop.png and b/e2e/visual-snapshots/visual-firefox-desktop/visual-regression.spec.ts/theme-dark-main-visual-firefox-desktop.png differ diff --git a/e2e/visual-snapshots/visual-firefox-desktop/visual-regression.spec.ts/theme-light-main-visual-firefox-desktop.png b/e2e/visual-snapshots/visual-firefox-desktop/visual-regression.spec.ts/theme-light-main-visual-firefox-desktop.png index 7dae458..c382d06 100644 Binary files a/e2e/visual-snapshots/visual-firefox-desktop/visual-regression.spec.ts/theme-light-main-visual-firefox-desktop.png and b/e2e/visual-snapshots/visual-firefox-desktop/visual-regression.spec.ts/theme-light-main-visual-firefox-desktop.png differ diff --git a/e2e/visual-snapshots/visual-webkit-desktop/visual-regression.spec.ts/home-fullpage-visual-webkit-desktop.png b/e2e/visual-snapshots/visual-webkit-desktop/visual-regression.spec.ts/home-fullpage-visual-webkit-desktop.png index ae2a3c7..031bbf6 100644 Binary files a/e2e/visual-snapshots/visual-webkit-desktop/visual-regression.spec.ts/home-fullpage-visual-webkit-desktop.png and b/e2e/visual-snapshots/visual-webkit-desktop/visual-regression.spec.ts/home-fullpage-visual-webkit-desktop.png differ diff --git a/e2e/visual-snapshots/visual-webkit-desktop/visual-regression.spec.ts/theme-dark-main-visual-webkit-desktop.png b/e2e/visual-snapshots/visual-webkit-desktop/visual-regression.spec.ts/theme-dark-main-visual-webkit-desktop.png index ae2a3c7..17162f7 100644 Binary files a/e2e/visual-snapshots/visual-webkit-desktop/visual-regression.spec.ts/theme-dark-main-visual-webkit-desktop.png and b/e2e/visual-snapshots/visual-webkit-desktop/visual-regression.spec.ts/theme-dark-main-visual-webkit-desktop.png differ diff --git a/e2e/visual-snapshots/visual-webkit-desktop/visual-regression.spec.ts/theme-light-main-visual-webkit-desktop.png b/e2e/visual-snapshots/visual-webkit-desktop/visual-regression.spec.ts/theme-light-main-visual-webkit-desktop.png index ae2a3c7..17162f7 100644 Binary files a/e2e/visual-snapshots/visual-webkit-desktop/visual-regression.spec.ts/theme-light-main-visual-webkit-desktop.png and b/e2e/visual-snapshots/visual-webkit-desktop/visual-regression.spec.ts/theme-light-main-visual-webkit-desktop.png differ diff --git a/src/app/(marketing)/contact/contact-content-v3.test.tsx b/src/app/(marketing)/contact/contact-content-v3.test.tsx index 5a5fcf5..3bebb3b 100644 --- a/src/app/(marketing)/contact/contact-content-v3.test.tsx +++ b/src/app/(marketing)/contact/contact-content-v3.test.tsx @@ -370,10 +370,19 @@ describe('ContactContentV3 - 联系表单集成测试', () => { // 成功消息同时出现在 form 成功状态和 toast 中,用 getAllByText expect(screen.getAllByText('感谢您的留言,我们会尽快与您联系。').length).toBeGreaterThanOrEqual(1); - // Should have called analytics + // Should have called analytics exactly once via trackContactForm const { trackContactForm, trackConversion } = await import('@/lib/analytics'); - expect(trackContactForm).toHaveBeenCalled(); - expect(trackConversion).toHaveBeenCalledWith('contact_form_submission'); + expect(trackContactForm).toHaveBeenCalledTimes(1); + expect(trackContactForm).toHaveBeenCalledWith( + expect.objectContaining({ + name: '张三', + email: 'zhangsan@example.com', + company: '咨询产品方案', + }), + true, + ); + // trackConversion 不应再被显式调用,避免重复上报 conversion + expect(trackConversion).not.toHaveBeenCalled(); }); it('should show error toast when API returns error', async () => { diff --git a/src/app/(marketing)/contact/contact-content-v3.tsx b/src/app/(marketing)/contact/contact-content-v3.tsx index f5c835f..708c65e 100644 --- a/src/app/(marketing)/contact/contact-content-v3.tsx +++ b/src/app/(marketing)/contact/contact-content-v3.tsx @@ -19,7 +19,7 @@ import { HelpCircle, ArrowRight, } from 'lucide-react'; -import { trackContactForm, trackConversion } from '@/lib/analytics'; +import { trackContactForm } from '@/lib/analytics'; import { BreadcrumbSchema } from '@/components/seo/structured-data'; import { LegacyTooltip as Tooltip } from '@/components/ui/tooltip'; @@ -166,12 +166,16 @@ function ContactFormContent({ data }: { data: ContactData }) { const resultData = await response.json(); if (response.ok && (resultData.success === 'true' || resultData.success === true)) { - trackContactForm({ - name: formData.name, - email: formData.email, - company: formData.subject, - }); - trackConversion('contact_form_submission'); + // trackContactForm 内部已发送 form_submit 事件并触发 conversion, + // 不再额外调用 trackConversion,避免同一个提交被重复计为两次转化。 + trackContactForm( + { + name: formData.name, + email: formData.email, + company: formData.subject, + }, + true, + ); setToastMessage(data.successMessage || '提交成功!我们会尽快与您联系。'); setToastType('success'); setShowToast(true); diff --git a/src/app/(marketing)/home-content-v14.tsx b/src/app/(marketing)/home-content-v14.tsx index daedaee..2a2f873 100644 --- a/src/app/(marketing)/home-content-v14.tsx +++ b/src/app/(marketing)/home-content-v14.tsx @@ -1,12 +1,14 @@ 'use client'; import { useRef } from 'react'; +import Image from 'next/image'; import { motion } from 'framer-motion'; import { ScrollReveal, StaggerReveal } from '@/components/ui/scroll-reveal'; import { Badge } from '@/components/ui/badge'; import { ArrowRight, Lightbulb, Database, Layers } from 'lucide-react'; import { cn } from '@/lib/utils'; import { EASE_OUT } from '@/components/ui/page-decoration'; +import { COMPANY_INFO } from '@/lib/constants'; // ===== 服务数据降级兜底 ===== const FALLBACK_SERVICES = [ @@ -104,6 +106,31 @@ function HeroSection({ heroData, stats }: {