import { expect, type Page, type Route, test } from "@playwright/test"; type ThemeCase = { name: "light" | "dark"; }; const themeCases: ThemeCase[] = [{ name: "light" }, { name: "dark" }]; async function mockSignupApis(page: Page): Promise { await page.route("**/api/v1/**", async (route: Route) => { const request = route.request(); const requestUrl = new URL(request.url()); const path = requestUrl.pathname; const method = request.method().toUpperCase(); if (path.endsWith("/api/v1/user/me")) { await route.fulfill({ status: 401, contentType: "application/json", body: JSON.stringify({ error: "unauthorized" }), }); return; } if (path.endsWith("/api/v1/auth/password/policy")) { await route.fulfill({ status: 200, contentType: "application/json", body: JSON.stringify({ minLength: 12, minCharacterTypes: 3, lowercase: true, uppercase: true, number: true, nonAlphanumeric: true, }), }); return; } if (path.endsWith("/api/v1/auth/signup/check-email") && method === "POST") { await route.fulfill({ status: 200, contentType: "application/json", body: JSON.stringify({ available: true }), }); return; } if ( (path.endsWith("/api/v1/auth/signup/send-email-code") || path.endsWith("/api/v1/auth/signup/send-sms-code")) && method === "POST" ) { await route.fulfill({ status: 200, contentType: "application/json", body: JSON.stringify({ ok: true }), }); return; } if (path.endsWith("/api/v1/auth/signup/verify-code") && method === "POST") { await route.fulfill({ status: 200, contentType: "application/json", body: JSON.stringify({ success: true, isAffiliate: false }), }); return; } if (path.endsWith("/api/v1/auth/signup") && method === "POST") { await route.fulfill({ status: 200, contentType: "application/json", body: JSON.stringify({ ok: true }), }); return; } if (path.endsWith("/api/v1/auth/tenant-info")) { await route.fulfill({ status: 200, contentType: "application/json", body: JSON.stringify({}), }); return; } if (path.endsWith("/api/v1/client-log")) { await route.fulfill({ status: 200, contentType: "application/json", body: JSON.stringify({ ok: true }), }); return; } await route.fulfill({ status: 200, contentType: "application/json", body: JSON.stringify({}), }); }); } async function enableFlutterAccessibility(page: Page): Promise { await page.waitForTimeout(300); const button = page.getByRole("button", { name: "Enable accessibility" }); const placeholder = page.locator("flt-semantics-placeholder").first(); await button.click({ force: true, timeout: 1_000 }).catch(async () => { await placeholder.click({ force: true, timeout: 1_000 }).catch(async () => { await placeholder.evaluate((node) => { (node as HTMLElement).click(); }); }); }); await page.waitForTimeout(400); } test.describe("UserFront signup theme visibility", () => { for (const theme of themeCases) { test(`signup keeps ${theme.name} theme colors visible across steps`, async ({ page, }) => { await mockSignupApis(page); if (theme.name === "dark") { await page.goto("/ko/signin", { waitUntil: "domcontentloaded" }); await page.waitForTimeout(1200); await enableFlutterAccessibility(page); const themeToggle = page.getByRole("button", { name: /Light|Dark|테마 전환|Theme toggle/i, }); await themeToggle.click({ force: true }); await page.waitForTimeout(500); } await page.goto("/ko/signup", { waitUntil: "domcontentloaded" }); await page.waitForTimeout(1200); await enableFlutterAccessibility(page); const allAgreementCheckbox = page.getByRole("checkbox", { name: /모두 동의합니다|Agree to all/i, }); await expect(allAgreementCheckbox).toBeVisible(); await allAgreementCheckbox.click({ force: true }); await expect(allAgreementCheckbox).toBeChecked(); const nextButton = page.getByRole("button", { name: /다음 단계|Next/i }); await expect(nextButton).toBeVisible(); await expect(nextButton).toBeEnabled(); await nextButton.click({ force: true }); await expect( page.getByText(/본인 확인을 위해|Verify your email and phone number/i), ).toBeVisible(); const emailInput = page.getByRole("textbox", { name: /이메일 주소|Email address/i, }); const phoneInput = page.getByRole("textbox", { name: /휴대폰 번호|Phone number/i, }); const requestButtons = page .getByRole("button") .filter({ hasText: /인증요청|재발송|Send code|Resend/i }); await expect(emailInput).toBeVisible(); await expect(phoneInput).toBeVisible(); await expect(requestButtons.nth(0)).toBeVisible(); await expect(requestButtons.nth(1)).toBeVisible(); await expect(nextButton).toBeVisible(); }); } });