From ab95af4b69d3e80b794828a1d9f5d1fc14e9a5fa Mon Sep 17 00:00:00 2001 From: mortezaei Date: Sat, 5 Sep 2026 14:44:51 +0330 Subject: [PATCH] refactor: replace hardcoded layout margins with global --app-shell-px variable and add regression tests --- .../finding-match/finding-match-client.tsx | 2 +- src/app/globals.css | 10 +- src/app/intro/intro-client.tsx | 2 +- src/app/questions-list/[slug]/loading.tsx | 2 +- .../[slug]/question-detail-client.tsx | 12 +- .../[slug]/question-dimensions.test.tsx | 123 ++++++++++++++++++ .../[slug]/test-intro-client.tsx | 2 +- src/components/Componentes/page-header.tsx | 4 +- .../Componentes/page-loading-skeleton.tsx | 4 +- .../Componentes/test-loading-screen.tsx | 2 +- .../Componentes/test-questions-flow.tsx | 2 +- 11 files changed, 147 insertions(+), 18 deletions(-) create mode 100644 src/app/questions-list/[slug]/question-dimensions.test.tsx diff --git a/src/app/finding-match/finding-match-client.tsx b/src/app/finding-match/finding-match-client.tsx index bbc7f6a..e8b0b6d 100644 --- a/src/app/finding-match/finding-match-client.tsx +++ b/src/app/finding-match/finding-match-client.tsx @@ -157,7 +157,7 @@ export default function FindingMatchClient() {
+
{/* Header placeholder */}
-
+
-
+
-
+
-
+

{isError ? locale === "fa" @@ -779,7 +779,7 @@ export default function QuestionDetailClient({ return ( <> -

+
-
+
{ + cleanup(); +}); + +vi.mock("next/navigation", () => ({ + useRouter: () => ({ + push: vi.fn(), + replace: vi.fn(), + back: vi.fn(), + }), +})); + +vi.mock("@/hooks/marriage/use-profile-main", () => ({ + useMarriageProfileQuery: () => ({ + data: undefined, + isLoading: false, + isFetched: true, + }), +})); + +describe("Dimensions & Padding Integrity Verification", () => { + it("globals.css preserves --app-shell-px and padding-inline on section-overlay", () => { + const cssPath = path.resolve(process.cwd(), "src/app/globals.css"); + const cssContent = fs.readFileSync(cssPath, "utf-8"); + + // Verify .section-overlay defines --app-shell-px: 17px and padding-inline: var(--app-shell-px) + expect(cssContent).toMatch( + /\.section-overlay\s*\{[\s\S]*?--app-shell-px:\s*17px;/, + ); + expect(cssContent).toMatch( + /\.section-overlay\s*\{[\s\S]*?padding-inline:\s*var\(--app-shell-px\);/, + ); + + // Verify tablet responsive padding for .section-overlay + expect(cssContent).toMatch( + /@media\s*\(min-width:\s*600px\)\s*\{[\s\S]*?\.section-overlay\s*\{[\s\S]*?--app-shell-px:\s*clamp\(24px,\s*5vw,\s*48px\);/, + ); + + // Verify .section-overlay does NOT have zeroed out padding or 0px app-shell-px + expect(cssContent).not.toMatch( + /\.section-overlay\s*\{[\s\S]*?--app-shell-px:\s*0px;/, + ); + + // Verify .question-detail-main rule exists with breakout margin + expect(cssContent).toMatch( + /\.question-detail-main\s*\{[\s\S]*?margin-inline:\s*calc\(-1\s*\*\s*var\(--app-shell-px,\s*17px\)\);/, + ); + }); + + it("FixToTheEnd retains var(--app-shell-px, 17px) padding for bottom buttons", () => { + const { container } = render( + + + , + ); + + const fixToEndEl = container.querySelector( + ".question-fix-to-end", + ) as HTMLElement; + expect(fixToEndEl).toBeInTheDocument(); + expect(fixToEndEl.style.paddingInline).toBe("var(--app-shell-px, 17px)"); + expect(fixToEndEl.style.paddingBottom).toBe( + "calc(16px + var(--safe-bottom))", + ); + }); + + it("PageHeader applies full breakout marginInline and content paddingInline", () => { + const { container } = render( + + + , + ); + + const headerEl = container.querySelector("header") as HTMLElement; + expect(headerEl).toBeInTheDocument(); + expect(headerEl.style.marginInline).toBe( + "calc(-1 * var(--app-shell-px, 17px))", + ); + expect(headerEl.style.paddingInline).toBe("var(--app-shell-px, 17px)"); + }); + + it("StickyHeader renders correctly with safe-area + 4px and rounded bottom", () => { + const { container } = render( + +

Question Title

+
, + ); + + const headerEl = container.querySelector("header") as HTMLElement; + expect(headerEl).toBeInTheDocument(); + expect(headerEl.className).toContain("rounded-b-[15px]"); + expect(headerEl.className).toContain( + "bg-[linear-gradient(135deg,#E03950_0%,#FE6F82_100%)]", + ); + }); + + it("all question detail main elements use question-detail-main class instead of hardcoded -mx-[17px]", () => { + const detailClientPath = path.resolve( + process.cwd(), + "src/app/questions-list/[slug]/question-detail-client.tsx", + ); + const content = fs.readFileSync(detailClientPath, "utf-8"); + + // No hardcoded -mx-[17px] on
+ expect(content).not.toMatch(/]*className="[^"]*-mx-\[17px\]/); + + // Matches question-detail-main on
+ const mainMatches = content.match( + /]*className="[^"]*question-detail-main/g, + ); + expect(mainMatches).not.toBeNull(); + expect(mainMatches!.length).toBeGreaterThanOrEqual(4); + }); +}); diff --git a/src/app/questions-list/[slug]/test-intro-client.tsx b/src/app/questions-list/[slug]/test-intro-client.tsx index db83711..eb1cfee 100644 --- a/src/app/questions-list/[slug]/test-intro-client.tsx +++ b/src/app/questions-list/[slug]/test-intro-client.tsx @@ -32,7 +32,7 @@ export default function TestIntroClient({ return ( <> -
+
{/* Header */}
@@ -68,7 +68,7 @@ export function PageLoadingSkeleton({
diff --git a/src/components/Componentes/test-loading-screen.tsx b/src/components/Componentes/test-loading-screen.tsx index 7917ee4..dff8b9a 100644 --- a/src/components/Componentes/test-loading-screen.tsx +++ b/src/components/Componentes/test-loading-screen.tsx @@ -15,7 +15,7 @@ export default function TestLoadingScreen(_props: TestLoadingScreenProps) {
diff --git a/src/components/Componentes/test-questions-flow.tsx b/src/components/Componentes/test-questions-flow.tsx index 637c734..8b33942 100644 --- a/src/components/Componentes/test-questions-flow.tsx +++ b/src/components/Componentes/test-questions-flow.tsx @@ -238,7 +238,7 @@ export default function TestQuestionsFlow({ return ( <> -
+
{/* Header */}