|
| 1 | +import { test, expect } from '@playwright/test'; |
| 2 | +import path from 'path'; |
| 3 | + |
| 4 | +// 백엔드 .env.local의 ADMIN_KEY (개발 환경 기본값) |
| 5 | +const ADMIN_KEY = process.env.E2E_ADMIN_KEY ?? 'ittda_admin'; |
| 6 | +const ANNOUNCEMENT_TITLE = 'E2E 테스트 공지사항'; |
| 7 | + |
| 8 | +// /api/admin/announcements → Next.js 프록시 → 백엔드 /v1/admin/announcements |
| 9 | +async function createAnnouncement( |
| 10 | + request: import('@playwright/test').APIRequestContext, |
| 11 | +): Promise<string> { |
| 12 | + const res = await request.post('/api/admin/announcements', { |
| 13 | + headers: { 'x-admin-key': ADMIN_KEY, 'Content-Type': 'application/json' }, |
| 14 | + data: { |
| 15 | + title: ANNOUNCEMENT_TITLE, |
| 16 | + content: 'E2E 테스트 중 생성된 공지입니다.', |
| 17 | + isActive: true, |
| 18 | + }, |
| 19 | + }); |
| 20 | + const body = await res.json(); |
| 21 | + if (!body.data?.id) throw new Error(`공지 생성 실패: ${JSON.stringify(body)}`); |
| 22 | + return body.data.id; |
| 23 | +} |
| 24 | + |
| 25 | +async function deleteAnnouncement( |
| 26 | + request: import('@playwright/test').APIRequestContext, |
| 27 | + id: string, |
| 28 | +): Promise<void> { |
| 29 | + await request.delete(`/api/admin/announcements/${id}`, { |
| 30 | + headers: { 'x-admin-key': ADMIN_KEY }, |
| 31 | + }); |
| 32 | +} |
| 33 | + |
| 34 | +test.describe('홈 공지사항 팝업', () => { |
| 35 | + let announcementId: string; |
| 36 | + |
| 37 | + test.use({ storageState: path.join(__dirname, '.auth/guest.json') }); |
| 38 | + |
| 39 | + test.beforeAll(async ({ request }) => { |
| 40 | + // isActive: true 생성 시 기존 활성 공지가 자동 비활성화됨 |
| 41 | + announcementId = await createAnnouncement(request); |
| 42 | + }); |
| 43 | + |
| 44 | + test.afterAll(async ({ request }) => { |
| 45 | + await deleteAnnouncement(request, announcementId); |
| 46 | + }); |
| 47 | + |
| 48 | + test('활성 공지사항이 있으면 홈 진입 시 팝업 모달이 표시된다', async ({ page }) => { |
| 49 | + await page.goto('/'); |
| 50 | + await expect( |
| 51 | + page.getByText(ANNOUNCEMENT_TITLE), |
| 52 | + ).toBeVisible({ timeout: 8000 }); |
| 53 | + // 확인 버튼도 함께 표시된다 |
| 54 | + await expect(page.getByRole('button', { name: '확인' })).toBeVisible(); |
| 55 | + }); |
| 56 | + |
| 57 | + test('"확인" 버튼을 누르면 모달이 닫히고 다시 홈에 와도 팝업이 뜨지 않는다', async ({ page }) => { |
| 58 | + // 각 테스트는 test.use({ storageState })로 독립된 컨텍스트를 가지므로 |
| 59 | + // dismiss 쿠키가 없는 초기 상태로 시작됨 |
| 60 | + await page.goto('/'); |
| 61 | + await expect(page.getByText(ANNOUNCEMENT_TITLE)).toBeVisible({ timeout: 8000 }); |
| 62 | + |
| 63 | + // 2) 확인 버튼 클릭 → dismiss 쿠키 설정 + router.refresh() |
| 64 | + await page.getByRole('button', { name: '확인' }).click(); |
| 65 | + await expect(page.getByText(ANNOUNCEMENT_TITLE)).not.toBeVisible({ timeout: 5000 }); |
| 66 | + |
| 67 | + // 3) 홈 재진입 → 쿠키 기반으로 SSR에서 모달 렌더링 제외 |
| 68 | + await page.goto('/'); |
| 69 | + await expect(page.getByText(ANNOUNCEMENT_TITLE)).not.toBeVisible({ timeout: 5000 }); |
| 70 | + }); |
| 71 | +}); |
0 commit comments