53db2f63e3
- Add Server.AddInteractiveServerComponents() + AddInteractiveServerRenderMode() - Create Server AuthLayout for login form (MudBlazor) - Implement LoginSimple.razor with @rendermode InteractiveServer in Server project - Update App.razor: CascadingAuthenticationState + Router with AppAssembly=Server - Fix Client MudBlazor Providers in MainLayout + AuthLayout - Update Playwright tests: use dynamic selectors for MudTextField (auto-generated IDs) - Build: 0 errors, 0 warnings - API: /api/auth/login fully operational (200 OK confirmed) - Playwright E2E test: 1 passed Architecture: /login → Server InteractiveServer (MudBlazor form) / → Client WebAssembly (Dashboard) /api/* → Server Endpoints Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
95 lines
3.8 KiB
TypeScript
95 lines
3.8 KiB
TypeScript
import { test, expect } from '@playwright/test';
|
|
|
|
test('실제 로그인 성공 확인', async ({ page }) => {
|
|
console.log('\n╔════════════════════════════════════════════════════╗');
|
|
console.log('║ 실제 로그인 성공 테스트 ║');
|
|
console.log('╚════════════════════════════════════════════════════╝\n');
|
|
|
|
// 1. 로그인 페이지 접근
|
|
console.log('1️⃣ 로그인 페이지 접근...');
|
|
await page.goto('http://localhost:5265/login');
|
|
await page.waitForLoadState('networkidle');
|
|
await page.waitForTimeout(2000);
|
|
|
|
const initialUrl = page.url();
|
|
console.log(` 초기 URL: ${initialUrl}`);
|
|
|
|
// 2. 입력 필드 찾기
|
|
console.log('\n2️⃣ 입력 필드 확인...');
|
|
const usernameInput = page.locator('input[type="text"]').first();
|
|
const passwordInput = page.locator('input[type="password"]');
|
|
const loginButton = page.locator('button:has-text("로그인")');
|
|
|
|
await expect(usernameInput).toBeVisible();
|
|
console.log(' ✓ 아이디 입력 필드');
|
|
|
|
await expect(passwordInput).toBeVisible();
|
|
console.log(' ✓ 비밀번호 입력 필드');
|
|
|
|
await expect(loginButton).toBeVisible();
|
|
console.log(' ✓ 로그인 버튼');
|
|
|
|
// 3. 올바른 자격증명으로 로그인
|
|
console.log('\n3️⃣ 로그인 자격증명 입력...');
|
|
await usernameInput.fill('admin');
|
|
console.log(' ✓ 아이디: admin');
|
|
|
|
await passwordInput.fill('admin');
|
|
console.log(' ✓ 비밀번호: ****');
|
|
|
|
// 4. 로그인 버튼 클릭
|
|
console.log('\n4️⃣ 로그인 버튼 클릭...');
|
|
await loginButton.click();
|
|
console.log(' ✓ 클릭됨');
|
|
|
|
// 5. 응답 대기 (중요!)
|
|
console.log('\n5️⃣ 응답 대기 중...');
|
|
await page.waitForTimeout(3000);
|
|
|
|
// 6. 최종 URL 확인
|
|
const finalUrl = page.url();
|
|
console.log(`\n📍 최종 URL: ${finalUrl}`);
|
|
|
|
// 7. 페이지 제목 확인
|
|
const pageTitle = await page.title();
|
|
console.log(`📄 페이지 제목: ${pageTitle}`);
|
|
|
|
// 8. 페이지 콘텐츠 확인
|
|
const bodyText = await page.locator('body').textContent();
|
|
console.log(`\n📝 페이지 텍스트 포함 여부:`);
|
|
|
|
if (bodyText?.includes('대시보드')) {
|
|
console.log(' ✅ "대시보드" 포함됨 - 로그인 성공!');
|
|
} else {
|
|
console.log(' ❌ "대시보드" 미포함');
|
|
}
|
|
|
|
if (bodyText?.includes('로그인')) {
|
|
console.log(' ⚠️ "로그인" 텍스트 여전히 표시됨 - 로그인 실패?');
|
|
}
|
|
|
|
// 9. 에러 메시지 확인
|
|
const errorText = await page.locator('.mud-alert-message, [role="alert"]').textContent();
|
|
if (errorText) {
|
|
console.log(`\n❌ 에러 메시지: ${errorText}`);
|
|
}
|
|
|
|
// 10. 스크린샷
|
|
await page.screenshot({ path: 'test-results/real-login-result.png', fullPage: true });
|
|
console.log('\n📸 스크린샷: test-results/real-login-result.png');
|
|
|
|
// 11. 최종 판단
|
|
console.log('\n╔════════════════════════════════════════════════════╗');
|
|
if (finalUrl.includes('/dashboard') || pageTitle.includes('대시보드')) {
|
|
console.log('║ ✅ 로그인 성공! ║');
|
|
} else if (finalUrl.includes('/login')) {
|
|
console.log('║ ❌ 로그인 실패 (로그인 페이지 유지) ║');
|
|
} else {
|
|
console.log(`║ ⚠️ 불명확한 상태: ${finalUrl}`);
|
|
}
|
|
console.log('╚════════════════════════════════════════════════════╝\n');
|
|
|
|
// 어설션
|
|
expect(finalUrl).not.toContain('/login');
|
|
});
|