test(mobile): add mobile E2E test suite (53 tests) and fix layout issues

Add comprehensive mobile testing coverage:
- Add chromium-mobile functional test project (iPhone 14, isMobile, hasTouch)
- Add mobile user journey tests (UJ-01/02/04/05/10 mobile variants)
- Add mobile performance baseline tests (FCP/LCP/load time)
- Add mobile accessibility tests (axe-core WCAG 2.1 AA, touch targets,
  form labels, alt text, contrast)
- Update README with progress and new npm scripts

Fix pre-existing issues:
- Fix footer component layout and test assertions
- Fix admin content page sidebar navigation and breadcrumb
- Fix standalone products page metadata and layout
- Fix product detail/service value sections
- Fix contact form layout on mobile
- Fix navigation constants and products data
- Fix layout.tsx CMS config and theme handling
- Fix erp-upgrade content layout
This commit is contained in:
2026-08-03 18:32:29 +08:00
parent f4d8f0a8e9
commit f3fc969bef
20 changed files with 1095 additions and 93 deletions
@@ -161,7 +161,7 @@ export function ProductValueSection({ product }: ProductValueSectionProps) {
}`}>
<Icon className="w-5 h-5" />
</div>
<div className="flex-1 min-w-0 pt-1">
<div className="flex-1 min-w-0 mt-3">
<FeatureTags text={feature} />
</div>
</div>
+2 -2
View File
@@ -68,7 +68,7 @@ export function ServiceValueSection({ service }: ServiceValueSectionProps) {
}}
className="bain-card p-6"
>
<div className="flex items-start gap-4">
<div className="flex items-center gap-4">
<div className={`shrink-0 w-11 h-11 flex items-center justify-center ${
index === 0
? 'bg-brand text-white'
@@ -76,7 +76,7 @@ export function ServiceValueSection({ service }: ServiceValueSectionProps) {
}`}>
<Icon className="w-5 h-5" />
</div>
<p className="text-sm font-medium text-text-secondary leading-relaxed pt-2">
<p className="text-sm font-medium text-text-secondary leading-relaxed">
{feature.split(':')[1] || feature}
</p>
</div>
+13 -1
View File
@@ -181,10 +181,11 @@ describe('Footer', () => {
expect(screen.getByTestId('card-solutions')).toBeInTheDocument();
});
it('should render contact card with contact info and QR code', () => {
it('should render contact card with contact info and QR codes', () => {
render(<Footer />);
expect(screen.getByTestId('card-contact')).toBeInTheDocument();
expect(screen.getByText('关注公众号')).toBeInTheDocument();
expect(screen.getByText('业务咨询')).toBeInTheDocument();
});
});
@@ -255,9 +256,20 @@ describe('Footer', () => {
expect(qrCode).toBeInTheDocument();
});
it('should render business QR code image', () => {
render(<Footer />);
const qrCode = screen.getByAltText('业务咨询微信二维码');
expect(qrCode).toBeInTheDocument();
});
it('should render WeChat QR code description', () => {
render(<Footer />);
expect(screen.getByText('关注公众号')).toBeInTheDocument();
});
it('should render business QR code description', () => {
render(<Footer />);
expect(screen.getByText('业务咨询')).toBeInTheDocument();
});
});
});
+26 -11
View File
@@ -86,17 +86,32 @@ export function Footer() {
</a>
</li>
</ul>
<div>
<p className="text-xs text-gray-400 mb-3 tracking-wide">关注公众号</p>
<div className="inline-block p-2 border border-gray-800 bg-gray-900">
<Image
src="/images/qrcode.webp"
alt="微信公众号二维码"
width={96}
height={96}
className="w-24 h-24"
loading="lazy"
/>
<div className="flex gap-6">
<div>
<p className="text-xs text-gray-400 mb-3 tracking-wide">关注公众号</p>
<div className="inline-block p-2 border border-gray-800 bg-gray-900">
<Image
src="/images/qrcode.webp"
alt="微信公众号二维码"
width={96}
height={96}
className="w-24 h-24"
loading="lazy"
/>
</div>
</div>
<div>
<p className="text-xs text-gray-400 mb-3 tracking-wide">业务咨询</p>
<div className="inline-block p-2 border border-gray-800 bg-gray-900">
<Image
src="/images/wechat-business-qr.webp"
alt="业务咨询微信二维码"
width={96}
height={96}
className="w-24 h-24"
loading="lazy"
/>
</div>
</div>
</div>
</div>