fix: E2E 내비게이션 시 Blazor Dynamic Spinner 감지 및 MudDialog 고유 식별자 기반 native click 연동을 적용하여 비동기 클릭 유실 원천 차단
TaxBaik CI/CD / build-and-deploy (push) Successful in 53s
TaxBaik CI/CD / build-and-deploy (push) Successful in 53s
This commit is contained in:
@@ -6,6 +6,8 @@ const password = process.env.E2E_ADMIN_PASSWORD;
|
||||
const baseUrl = (process.env.E2E_BASE_URL ?? 'http://178.104.200.7/taxbaik').replace(/\/$/, '');
|
||||
|
||||
test.describe('admin CRM pages', () => {
|
||||
test.describe.configure({ mode: 'serial' });
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
test.skip(!password, 'E2E_ADMIN_PASSWORD is required.');
|
||||
await loginThroughAdminUi(page, baseUrl, username, password);
|
||||
@@ -124,11 +126,19 @@ test.describe('admin CRM pages', () => {
|
||||
|
||||
test('TaxProfiles form displays valid business type combo choices', async ({ page }) => {
|
||||
await navigateInBlazor(page, `${baseUrl}/admin/tax-profiles`);
|
||||
const addButton = page.getByRole('button', { name: /새 프로필 추가/ });
|
||||
await addButton.click();
|
||||
await expect(page.locator('.admin-grid, .mud-alert')).toBeVisible({ timeout: 15000 });
|
||||
|
||||
// Label을 매개로 인풋 영역 클릭
|
||||
await page.getByLabel('사업 유형').first().click();
|
||||
const addButton = page.getByRole('button', { name: /새 프로필 추가/ });
|
||||
|
||||
// JS 네이티브 클릭으로 강제 격발하여 오프셋 씹힘 소멸
|
||||
await addButton.evaluate(el => (el as HTMLButtonElement).click());
|
||||
|
||||
// 대화상자(MudDialog) 자체의 노출 대기
|
||||
await expect(page.locator('.mud-dialog')).toBeVisible({ timeout: 5000 });
|
||||
|
||||
// mud-select 컨테이너 자체 클릭 (이벤트 핸들러 직접 격발)
|
||||
const select = page.locator('.mud-select').filter({ hasText: '사업 유형' }).first();
|
||||
await select.evaluate(el => (el as HTMLDivElement).click());
|
||||
|
||||
// 활성화된 팝오버(.mud-popover-open) 내에서 텍스트 노출 검증
|
||||
const popover = page.locator('.mud-popover-open');
|
||||
@@ -139,10 +149,15 @@ test.describe('admin CRM pages', () => {
|
||||
|
||||
test('TaxFilingSchedules form displays filing type combo choices', async ({ page }) => {
|
||||
await navigateInBlazor(page, `${baseUrl}/admin/tax-filing-schedules`);
|
||||
const addButton = page.getByRole('button', { name: /새 일정 추가/ });
|
||||
await addButton.click();
|
||||
await expect(page.locator('.admin-grid, .mud-alert')).toBeVisible({ timeout: 15000 });
|
||||
|
||||
await page.getByLabel('신고 유형').first().click();
|
||||
const addButton = page.getByRole('button', { name: /새 일정 추가/ });
|
||||
await addButton.evaluate(el => (el as HTMLButtonElement).click());
|
||||
|
||||
await expect(page.locator('.mud-dialog')).toBeVisible({ timeout: 5000 });
|
||||
|
||||
const select = page.locator('.mud-select').filter({ hasText: '신고 유형' }).first();
|
||||
await select.evaluate(el => (el as HTMLDivElement).click());
|
||||
|
||||
const popover = page.locator('.mud-popover-open');
|
||||
await expect(popover.getByText('종합소득세')).toBeVisible({ timeout: 5000 });
|
||||
@@ -151,10 +166,15 @@ test.describe('admin CRM pages', () => {
|
||||
|
||||
test('Contracts form displays service type combo choices', async ({ page }) => {
|
||||
await navigateInBlazor(page, `${baseUrl}/admin/contracts`);
|
||||
const addButton = page.getByRole('button', { name: /새 계약 추가/ });
|
||||
await addButton.click();
|
||||
await expect(page.locator('.admin-grid, .mud-alert')).toBeVisible({ timeout: 15000 });
|
||||
|
||||
await page.getByLabel('서비스 유형').first().click();
|
||||
const addButton = page.getByRole('button', { name: /새 계약 추가/ });
|
||||
await addButton.evaluate(el => (el as HTMLButtonElement).click());
|
||||
|
||||
await expect(page.locator('.mud-dialog')).toBeVisible({ timeout: 5000 });
|
||||
|
||||
const select = page.locator('.mud-select').filter({ hasText: '서비스 유형' }).first();
|
||||
await select.evaluate(el => (el as HTMLDivElement).click());
|
||||
|
||||
const popover = page.locator('.mud-popover-open');
|
||||
await expect(popover.getByText('개인 기장대리')).toBeVisible({ timeout: 5000 });
|
||||
|
||||
@@ -58,6 +58,19 @@ export async function navigateInBlazor(page: Page, targetUrl: string) {
|
||||
|
||||
window.location.href = url;
|
||||
}, targetUrl);
|
||||
|
||||
// Wait until Blazor Server completes connection and hides the loading spinner overlay
|
||||
await page.locator('#blazor-loading').waitFor({ state: 'hidden', timeout: 15000 }).catch(() => {});
|
||||
|
||||
// Also wait for MudBlazor's dynamic loading spinners to disappear (ensuring the grid is interactive)
|
||||
const spinner = page.locator('.mud-progress-circular, .mud-progress-linear-bar');
|
||||
try {
|
||||
if (await spinner.count() > 0) {
|
||||
await spinner.first().waitFor({ state: 'hidden', timeout: 10000 });
|
||||
}
|
||||
} catch (e) {
|
||||
// Suppress timeout if the spinner was already gone or never showed up
|
||||
}
|
||||
}
|
||||
|
||||
export async function findInquiryByName(
|
||||
|
||||
Reference in New Issue
Block a user