/** * 옵션설정 (Option Settings) 페이지 반응형 동작 테스트 * - V2CategoryManagerComponent + ResponsiveGridRenderer * - 화면: http://localhost:9771/screens/1421 * * 실행: npx tsx scripts/test-option-settings-responsive.ts */ import { chromium } from "playwright"; import * as path from "path"; import * as fs from "fs"; const BASE_URL = "http://localhost:9771"; const API_URL = "http://localhost:8080/api"; const PAGE_URL = `${BASE_URL}/screens/1421`; const CREDENTIALS = [ { userId: "SUPER", password: "1234" }, { userId: "wace", password: "qlalfqjsgh11" }, ]; const OUTPUT_DIR = path.join(__dirname, "../test-output/option-settings-responsive"); async function loginViaApi(): Promise { for (const cred of CREDENTIALS) { const res = await fetch(`${API_URL}/auth/login`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ userId: cred.userId, password: cred.password }), }); const data = await res.json(); if (data.success && data.data?.token) { console.log(` Using credentials: ${cred.userId}`); return data.data.token; } } throw new Error("Login failed with all credentials"); } async function main() { fs.mkdirSync(OUTPUT_DIR, { recursive: true }); const token = await loginViaApi(); console.log("1. Logged in via API"); const browser = await chromium.launch({ headless: true }); const context = await browser.newContext({ viewport: { width: 1400, height: 900 }, }); const page = await context.newPage(); const consoleErrors: string[] = []; const reactHookErrors: string[] = []; page.on("console", (msg) => { const type = msg.type(); const text = msg.text(); if (type === "error") { consoleErrors.push(text); if (text.includes("order of Hooks") || text.includes("React has detected")) { reactHookErrors.push(text); } } }); try { console.log("2. Loading login page to inject token..."); await page.goto(`${BASE_URL}/login`, { waitUntil: "domcontentloaded", timeout: 15000 }); await page.evaluate((t: string) => { localStorage.setItem("authToken", t); document.cookie = `authToken=${t}; path=/; max-age=86400; SameSite=Lax`; }, token); console.log("3. Navigating to Option Settings page (screens/1421)..."); await page.goto(PAGE_URL, { waitUntil: "domcontentloaded", timeout: 15000 }); await page.waitForTimeout(5000); const report: string[] = []; const widths = [ { w: 1400, name: "1-desktop-1400px" }, { w: 1100, name: "2-tablet-1100px" }, { w: 900, name: "3-tablet-900px" }, { w: 600, name: "4-mobile-600px" }, { w: 1400, name: "5-desktop-1400px-restored" }, ]; for (const { w, name } of widths) { console.log(`\nResizing to ${w}px...`); await page.setViewportSize({ width: w, height: w === 600 ? 812 : 900 }); await page.waitForTimeout(1500); const filePath = path.join(OUTPUT_DIR, `${name}.png`); await page.screenshot({ path: filePath, fullPage: false }); console.log(` Saved: ${filePath}`); const hasCategoryColumn = (await page.locator('text=카테고리 컬럼').count()) > 0; const hasUseStatus = (await page.locator('text=사용여부').count()) > 0; const hasVerticalStack = (await page.locator('button:has-text("목록")').count()) > 0; const hasLeftRightSplit = (await page.locator('[class*="cursor-col-resize"]').count()) > 0; report.push(`[${w}px] Category column: ${hasCategoryColumn}, Use status: ${hasUseStatus}, Vertical: ${hasVerticalStack}, Split: ${hasLeftRightSplit}`); } console.log("\n" + "=".repeat(60)); console.log("OPTION SETTINGS RESPONSIVE TEST REPORT"); console.log("=".repeat(60)); report.forEach((r) => console.log(r)); if (consoleErrors.length > 0) { console.log("\n--- Console Errors ---"); consoleErrors.slice(0, 10).forEach((e) => console.log(" ", e)); } if (reactHookErrors.length > 0) { console.log("\n--- React Hook Errors (order of Hooks) ---"); reactHookErrors.forEach((e) => console.log(" ", e)); } fs.writeFileSync( path.join(OUTPUT_DIR, "report.txt"), [ "OPTION SETTINGS RESPONSIVE TEST REPORT", "=".repeat(50), ...report, "", "Console errors: " + consoleErrors.length, "React Hook errors: " + reactHookErrors.length, ...reactHookErrors.map((e) => " " + e), ].join("\n") ); console.log("\nScreenshots saved to:", OUTPUT_DIR); } catch (e) { console.error("Error:", e); throw e; } finally { await browser.close(); } } main();