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:
+34
-4
@@ -14,7 +14,7 @@ import { ScrollProgress } from "@/components/ui/scroll-progress";
|
||||
import { BackToTop } from "@/components/ui/back-to-top";
|
||||
import { ClientLayout } from "@/components/layout/client-layout";
|
||||
import { getPublishedItems } from "@/lib/cms/data-server";
|
||||
import { SiteConfigProvider, type SiteConfig, type NavigationItem, type MegaDropdownGroup } from "@/lib/site-config";
|
||||
import { SiteConfigProvider, type SiteConfig, type NavigationItem, type MegaDropdownGroup, type MegaDropdownItem } from "@/lib/site-config";
|
||||
import { COMPANY_INFO } from "@/lib/constants/company";
|
||||
import { NAVIGATION_V2, MEGA_DROPDOWN_DATA } from "@/lib/constants/navigation";
|
||||
|
||||
@@ -82,15 +82,45 @@ export default async function RootLayout({
|
||||
}: Readonly<{
|
||||
children: React.ReactNode;
|
||||
}>) {
|
||||
// Fetch site configuration and navigation from CMS
|
||||
const [navItems, configItems] = await Promise.all([
|
||||
// Fetch site configuration, navigation, and standalone products from CMS
|
||||
const [navItems, configItems, standaloneItems] = await Promise.all([
|
||||
getPublishedItems('navigation').catch(() => []),
|
||||
getPublishedItems('site-config').catch(() => []),
|
||||
getPublishedItems('standalone-product').catch(() => []),
|
||||
]);
|
||||
|
||||
const navData = navItems[0]?.data as Record<string, unknown> | undefined;
|
||||
const configData = configItems[0]?.data as Record<string, unknown> | undefined;
|
||||
|
||||
// Generate standalone product navigation items from CMS data
|
||||
const standaloneNavItems: MegaDropdownItem[] = standaloneItems.map((item) => {
|
||||
const data = item.data as Record<string, unknown>;
|
||||
const externalUrl = data.externalUrl as string | undefined;
|
||||
return {
|
||||
id: (data.id as string) || item.slug || '',
|
||||
title: (data.title as string) || item.title,
|
||||
description: (data.description as string) || '',
|
||||
href: externalUrl || `/products/standalone/${item.slug || data.id}`,
|
||||
badge: (data.status as string) === '内测中' ? '内测中' : undefined,
|
||||
};
|
||||
});
|
||||
|
||||
// Build megaDropdown with standalone products dynamically injected
|
||||
const baseMegaDropdown = (navData?.megaDropdown as Record<string, MegaDropdownGroup[]>) || MEGA_DROPDOWN_DATA;
|
||||
const megaDropdown: Record<string, MegaDropdownGroup[]> = {};
|
||||
for (const [key, groups] of Object.entries(baseMegaDropdown)) {
|
||||
if (key === 'products' && standaloneNavItems.length > 0) {
|
||||
megaDropdown[key] = groups.map((group) => {
|
||||
if (group.id === 'standalone-products') {
|
||||
return { ...group, description: undefined, items: standaloneNavItems };
|
||||
}
|
||||
return group;
|
||||
});
|
||||
} else {
|
||||
megaDropdown[key] = groups;
|
||||
}
|
||||
}
|
||||
|
||||
const siteConfig: SiteConfig = {
|
||||
name: (configData?.name as string) || COMPANY_INFO.name,
|
||||
shortName: (configData?.shortName as string) || COMPANY_INFO.shortName,
|
||||
@@ -104,7 +134,7 @@ export default async function RootLayout({
|
||||
icp: (configData?.icp as string) || COMPANY_INFO.icp,
|
||||
police: (configData?.police as string) || COMPANY_INFO.police,
|
||||
mainNav: (navData?.mainNav as NavigationItem[]) || NAVIGATION_V2,
|
||||
megaDropdown: (navData?.megaDropdown as Record<string, MegaDropdownGroup[]>) || MEGA_DROPDOWN_DATA,
|
||||
megaDropdown,
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user