Files
vexplor/scripts/browser-test-admin-switch-button.js
DDD1542 43ead0e7f2 feat: Enhance SelectedItemsDetailInputComponent with sourceKeyField auto-detection and FK mapping
- Implemented automatic detection of sourceKeyField based on component configuration, improving flexibility in data handling.
- Enhanced the SelectedItemsDetailInputConfigPanel to support automatic FK detection and mapping, streamlining the configuration process.
- Updated the database connection logic to handle DATE types correctly, preventing timezone-related issues.
- Improved overall component performance by optimizing memoization and state management for better user experience.
2026-02-26 16:39:06 +09:00

171 lines
5.7 KiB
JavaScript

/**
* 프로덕션에서 "관리자 메뉴로 전환" 버튼 가시성 테스트
* 두 계정 (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);
});