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>
75 lines
2.7 KiB
TypeScript
75 lines
2.7 KiB
TypeScript
import { test } from '@playwright/test';
|
|
|
|
test('상세 디버깅 - onclick 확인', async ({ page }) => {
|
|
console.log('\n╔════════════════════════════════════════════════════╗');
|
|
console.log('║ 상세 디버깅 - Blazor 상호작용 확인 ║');
|
|
console.log('╚════════════════════════════════════════════════════╝\n');
|
|
|
|
// 네트워크 추적
|
|
page.on('request', request => {
|
|
console.log(`📤 [REQUEST] ${request.method()} ${request.url()}`);
|
|
});
|
|
|
|
page.on('response', response => {
|
|
console.log(`📥 [RESPONSE] ${response.status()} ${response.url()}`);
|
|
});
|
|
|
|
// 콘솔 추적
|
|
page.on('console', msg => {
|
|
if (msg.type() === 'log') {
|
|
console.log(`🖨️ [LOG] ${msg.text()}`);
|
|
} else if (msg.type() === 'error') {
|
|
console.log(`❌ [ERROR] ${msg.text()}`);
|
|
}
|
|
});
|
|
|
|
console.log('1️⃣ 페이지 접근...');
|
|
await page.goto('http://localhost:5265/login');
|
|
await page.waitForLoadState('networkidle');
|
|
await page.waitForTimeout(2000);
|
|
|
|
console.log('\n2️⃣ 버튼 onclick 핸들러 확인...');
|
|
const loginButton = page.locator('button:has-text("로그인")');
|
|
|
|
const onclickCheck = await loginButton.evaluate((el: any) => {
|
|
console.log('Button element:', el);
|
|
console.log('onclick:', el.onclick);
|
|
console.log('data attributes:', Array.from(el.attributes).map((a: any) => `${a.name}=${a.value}`));
|
|
return {
|
|
onclick: el.onclick,
|
|
onclickString: el.onclick?.toString() || 'null',
|
|
attributes: Array.from(el.attributes).map((a: any) => `${a.name}=${a.value}`),
|
|
};
|
|
});
|
|
|
|
console.log(' onclick 확인 결과:');
|
|
console.log(` - onclick: ${onclickCheck.onclick}`);
|
|
console.log(` - 속성 목록:`);
|
|
onclickCheck.attributes.forEach((attr: string) => {
|
|
console.log(` • ${attr}`);
|
|
});
|
|
|
|
console.log('\n3️⃣ 입력 필드 확인...');
|
|
const usernameInput = page.locator('input[type="text"]').first();
|
|
const passwordInput = page.locator('input[type="password"]');
|
|
|
|
await usernameInput.fill('admin');
|
|
await passwordInput.fill('admin');
|
|
console.log(' 입력 완료');
|
|
|
|
console.log('\n4️⃣ 버튼 클릭...');
|
|
await loginButton.click();
|
|
console.log(' 클릭됨');
|
|
|
|
await page.waitForTimeout(3000);
|
|
|
|
console.log('\n5️⃣ 최종 상태...');
|
|
const finalUrl = page.url();
|
|
console.log(` URL: ${finalUrl}`);
|
|
|
|
// 버튼 상태 재확인
|
|
const isVisible = await loginButton.isVisible();
|
|
const isEnabled = await loginButton.isEnabled();
|
|
console.log(` 버튼 시각성: ${isVisible}, 활성화: ${isEnabled}`);
|
|
});
|