/** * 프로덕션에서 "관리자 메뉴로 전환" 버튼 가시성 테스트 * 두 계정 (topseal_admin, rsw1206)으로 로그인하여 버튼 표시 여부 확인 * * 실행: node scripts/browser-test-admin-switch-button.js * 브라우저 표시: HEADLESS=0 node scripts/browser-test-admin-switch-button.js */ const { chromium } = require("playwright"); const fs = require("fs"); const BASE_URL = "https://v1.vexplor.com"; const SCREENSHOT_DIR = "test-screenshots/admin-switch-test"; const ACCOUNTS = [ { userId: "topseal_admin", password: "qlalfqjsgh11", name: "topseal_admin" }, { userId: "rsw1206", password: "qlalfqjsgh11", name: "rsw1206" }, ]; async function runTest() { const results = { topseal_admin: {}, rsw1206: {} }; const browser = await chromium.launch({ headless: process.env.HEADLESS !== "0", }); const context = await browser.newContext({ viewport: { width: 1280, height: 900 }, ignoreHTTPSErrors: true, }); const page = await context.newPage(); try { if (!fs.existsSync(SCREENSHOT_DIR)) { fs.mkdirSync(SCREENSHOT_DIR, { recursive: true }); } const screenshot = async (name) => { const path = `${SCREENSHOT_DIR}/${name}.png`; await page.screenshot({ path, fullPage: true }); console.log(` [스크린샷] ${path}`); return path; }; for (let i = 0; i < ACCOUNTS.length; i++) { const acc = ACCOUNTS[i]; console.log(`\n========== ${acc.name} 테스트 (${i + 1}/${ACCOUNTS.length}) ==========\n`); // 로그인 페이지로 이동 await page.goto(`${BASE_URL}/login`, { waitUntil: "networkidle", timeout: 20000, }); await page.waitForTimeout(1000); // 로그인 await page.fill("#userId", acc.userId); await page.fill("#password", acc.password); await page.click('button[type="submit"]'); await page.waitForTimeout(3000); // 로그인 성공 시 대시보드 또는 메인으로 리다이렉트될 것임 const currentUrl = page.url(); if (currentUrl.includes("/login") && !currentUrl.includes("error")) { // 아직 로그인 페이지에 있다면 조금 더 대기 await page.waitForTimeout(3000); } const afterLoginUrl = page.url(); const screenshotPath = await screenshot(`01_${acc.name}_after_login`); // "관리자 메뉴로 전환" 버튼 찾기 const buttonSelectors = [ 'button:has-text("관리자 메뉴로 전환")', '[class*="button"]:has-text("관리자 메뉴로 전환")', 'button >> text=관리자 메뉴로 전환', ]; let buttonVisible = false; for (const sel of buttonSelectors) { try { const btn = page.locator(sel).first(); const count = await btn.count(); if (count > 0) { const isVisible = await btn.isVisible(); if (isVisible) { buttonVisible = true; break; } } } catch (_) {} } // 추가: 페이지 내 텍스트로 버튼 존재 여부 확인 if (!buttonVisible) { const pageText = await page.textContent("body"); buttonVisible = pageText && pageText.includes("관리자 메뉴로 전환"); } results[acc.name] = { buttonVisible, screenshotPath, afterLoginUrl, }; console.log(` 버튼 가시성: ${buttonVisible ? "표시됨" : "표시 안 됨"}`); console.log(` URL: ${afterLoginUrl}`); // 로그아웃 (다음 계정 테스트 전) if (i < ACCOUNTS.length - 1) { console.log("\n 로그아웃 중..."); try { // 프로필 드롭다운 클릭 (좌측 하단) const profileBtn = page.locator( 'button:has-text("로그아웃"), [class*="dropdown"]:has-text("로그아웃"), [data-radix-collection-item]:has-text("로그아웃")' ); const profileTrigger = page.locator( 'button[class*="flex w-full"][class*="gap-3"]' ).first(); if (await profileTrigger.count() > 0) { await profileTrigger.click(); await page.waitForTimeout(500); const logoutItem = page.locator('text=로그아웃').first(); if (await logoutItem.count() > 0) { await logoutItem.click(); await page.waitForTimeout(2000); } } // 또는 직접 로그아웃 URL if (page.url().includes("/login") === false) { await page.goto(`${BASE_URL}/api/auth/logout`, { waitUntil: "networkidle", timeout: 5000, }).catch(() => {}); await page.goto(`${BASE_URL}/login`, { waitUntil: "networkidle", timeout: 10000, }); } } catch (e) { console.log(" 로그아웃 대체: 로그인 페이지로 직접 이동"); await page.goto(`${BASE_URL}/login`, { waitUntil: "networkidle", timeout: 10000, }); } await page.waitForTimeout(1500); } } console.log("\n========== 최종 결과 ==========\n"); console.log("topseal_admin: 관리자 메뉴로 전환 버튼 =", results.topseal_admin.buttonVisible ? "표시됨" : "표시 안 됨"); console.log("rsw1206: 관리자 메뉴로 전환 버튼 =", results.rsw1206.buttonVisible ? "표시됨" : "표시 안 됨"); console.log("\n스크린샷:", SCREENSHOT_DIR); return results; } catch (err) { console.error("테스트 오류:", err); throw err; } finally { await browser.close(); } } runTest() .then((r) => { console.log("\n테스트 완료."); process.exit(0); }) .catch((e) => { console.error(e); process.exit(1); });