diff --git a/tests/e2e/admin-crm-pages.spec.ts b/tests/e2e/admin-crm-pages.spec.ts new file mode 100644 index 0000000..4eeba42 --- /dev/null +++ b/tests/e2e/admin-crm-pages.spec.ts @@ -0,0 +1,148 @@ +import { expect, test } from '@playwright/test'; +import { loginThroughAdminUi, navigateInBlazor } from './helpers/admin-auth'; + +const username = process.env.E2E_ADMIN_USERNAME ?? 'admin'; +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.beforeEach(async ({ page }) => { + test.skip(!password, 'E2E_ADMIN_PASSWORD is required.'); + await loginThroughAdminUi(page, baseUrl, username, password); + }); + + test('TaxProfiles page loads with grid and add button', async ({ page }) => { + await navigateInBlazor(page, `${baseUrl}/admin/tax-profiles`); + await expect(page).toHaveURL(/\/admin\/tax-profiles$/); + + // 제목 확인 + await expect(page.getByText('세무 프로필 관리')).toBeVisible({ timeout: 15_000 }); + + // 새 프로필 추가 버튼 확인 + await expect(page.getByRole('button', { name: /새 프로필 추가/ })).toBeVisible(); + + // MudDataGrid 로드 확인 (테이블 or 비어있음 메시지) + const gridOrEmpty = page.locator('.admin-grid, .mud-alert'); + await expect(gridOrEmpty).toBeVisible({ timeout: 15_000 }); + }); + + test('TaxFilingSchedules page loads with D-day tracking', async ({ page }) => { + await navigateInBlazor(page, `${baseUrl}/admin/tax-filing-schedules`); + await expect(page).toHaveURL(/\/admin\/tax-filing-schedules$/); + + // 제목 확인 + await expect(page.getByText('신고 일정 관리')).toBeVisible({ timeout: 15_000 }); + + // 새 일정 추가 버튼 + await expect(page.getByRole('button', { name: /새 일정 추가/ })).toBeVisible(); + + // 그리드 로드 + const gridOrEmpty = page.locator('.admin-grid, .mud-alert'); + await expect(gridOrEmpty).toBeVisible({ timeout: 15_000 }); + }); + + test('Contracts page loads with MRR display', async ({ page }) => { + await navigateInBlazor(page, `${baseUrl}/admin/contracts`); + await expect(page).toHaveURL(/\/admin\/contracts$/); + + // 제목 확인 + await expect(page.getByText('계약 관리')).toBeVisible({ timeout: 15_000 }); + + // 새 계약 추가 버튼 + await expect(page.getByRole('button', { name: /새 계약 추가/ })).toBeVisible(); + + // 그리드 로드 + const gridOrEmpty = page.locator('.admin-grid, .mud-alert'); + await expect(gridOrEmpty).toBeVisible({ timeout: 15_000 }); + }); + + test('ConsultingActivities page loads with activity records', async ({ page }) => { + await navigateInBlazor(page, `${baseUrl}/admin/consulting-activities`); + await expect(page).toHaveURL(/\/admin\/consulting-activities$/); + + // 제목 확인 + await expect(page.getByText('상담 활동 관리')).toBeVisible({ timeout: 15_000 }); + + // 새 활동 기록 버튼 + await expect(page.getByRole('button', { name: /새 활동 기록/ })).toBeVisible(); + + // 그리드 로드 + const gridOrEmpty = page.locator('.admin-grid, .mud-alert'); + await expect(gridOrEmpty).toBeVisible({ timeout: 15_000 }); + }); + + test('RevenueTrackings page loads with payment status tracking', async ({ page }) => { + await navigateInBlazor(page, `${baseUrl}/admin/revenue-trackings`); + await expect(page).toHaveURL(/\/admin\/revenue-trackings$/); + + // 제목 확인 + await expect(page.getByText('수익 추적 관리')).toBeVisible({ timeout: 15_000 }); + + // 새 청구 추가 버튼 + await expect(page.getByRole('button', { name: /새 청구 추가/ })).toBeVisible(); + + // 그리드 로드 + const gridOrEmpty = page.locator('.admin-grid, .mud-alert'); + await expect(gridOrEmpty).toBeVisible({ timeout: 15_000 }); + }); + + test('CRM navigation group is visible and expandable', async ({ page }) => { + await navigateInBlazor(page, `${baseUrl}/admin/dashboard`); + + // 좌측 패널 네비게이션 확인 + const crmGroup = page.getByText('CRM & 세무관리'); + await expect(crmGroup).toBeVisible({ timeout: 10_000 }); + + // CRM 그룹의 모든 링크 확인 + const expectedLinks = [ + '세무 프로필', + '신고 일정', + '계약 관리', + '상담 활동', + '수익 추적' + ]; + + for (const linkText of expectedLinks) { + const link = page.getByRole('link', { name: linkText }); + await expect(link).toBeVisible({ timeout: 10_000 }); + } + }); + + test('TaxProfiles modal dialog opens on add button click', async ({ page }) => { + await navigateInBlazor(page, `${baseUrl}/admin/tax-profiles`); + + // 추가 버튼 클릭 + const addButton = page.getByRole('button', { name: /새 프로필 추가/ }); + await addButton.click(); + + // 모달 열림 확인 (취소 버튼이 나타나야 함) + await expect(page.getByRole('button', { name: '취소' }).first()).toBeVisible({ timeout: 5_000 }); + + // 모달 폼 필드 확인 + await expect(page.locator('input[aria-label*="고객"]').or(page.locator('select'))).toBeVisible({ timeout: 5_000 }); + }); + + test('No console errors on CRM page navigation', async ({ page }) => { + const consoleErrors: string[] = []; + page.on('console', message => { + if (message.type() === 'error') { + consoleErrors.push(message.text()); + } + }); + + const crmPages = [ + '/admin/tax-profiles', + '/admin/tax-filing-schedules', + '/admin/contracts', + '/admin/consulting-activities', + '/admin/revenue-trackings' + ]; + + for (const path of crmPages) { + await navigateInBlazor(page, `${baseUrl}${path}`); + await page.waitForTimeout(2000); + } + + expect(consoleErrors, 'no console errors during CRM navigation').toEqual([]); + }); +});