-
Notifications
You must be signed in to change notification settings - Fork 3
[test] 지원하기 e2e 테스트 #1132
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop-fe
Are you sure you want to change the base?
[test] 지원하기 e2e 테스트 #1132
Conversation
- 커스텀 DOM 접근 오류 제거
- 기본 브라우저/모바일 디바이스, webServer 구동, 스크린샷·트레이스 옵션 포함 - 실제 네트워크 요청으로 테스트 실행
- DEV + VITE_DISABLE_MSW=true에서 기존 SW unregister로 e2e 오염 방지
- msw 버전 업데이트에 맞춰 mockServiceWorker.js 갱신
- 메인 → 상세 → 지원서 작성/제출 시나리오 검증
- playwright-report/, test-results/
- Node 타입 추가 및 Playwright 설정 파일 포함
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Warning Rate limit exceeded
⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. Warning
|
| Cohort / File(s) | Summary |
|---|---|
CI 및 E2E 인프라 .github/workflows/front-test.yml, frontend/playwright.config.ts, frontend/package.json, frontend/tsconfig.json, frontend/jest.config.js |
Frontend CI 워크플로우(프론트 lint/test/e2e/build) 추가, Playwright 설정·스크립트·의존성 추가, TS/Jest에 e2e 관련 제외·타입 추가 |
E2E 테스트 구현 frontend/e2e/apply-flow.spec.ts, frontend/e2e/fixture/mock-data.ts |
클럽 지원 플로우 Playwright E2E 테스트 추가(검색→상세→지원서 조회·작성·제출) 및 목 데이터 제공, 팝업 닫기 헬퍼·콘솔 로그 수집 포함 |
Mock Service Worker 변경 frontend/public/mockServiceWorker.js, frontend/src/index.tsx |
요청 직렬화(serializeRequest)·requestInterceptedAt 타임스탬프 도입, 응답 페이로드 확장 및 메시지 포맷 변경, VITE_DISABLE_MSW 처리(서비스워커 언등록) 및 MSW 초기화 보호 로직 추가 |
프로젝트 설정·무시 파일 frontend/.gitignore |
playwright-report/ 및 test-results/ 무시 패턴 추가 |
styled-components: 공통 컴포넌트 변경 frontend/src/components/.../Header/*, frontend/src/components/ClubTag/ClubTag.tsx, frontend/src/components/common/InputField/*, frontend/src/components/common/CustomTextArea/* |
여러 공통 컴포넌트에서 스타일용 props를 $ 접두사 트랜지언트로 일괄 변경(예: isScrolled→$isScrolled, width→$width, hasError→$hasError) 및 사용처 업데이트 |
styled-components: 페이지별 변경 frontend/src/pages/MainPage/components/*, frontend/src/pages/ClubDetailPage/components/PhotoModal/*, frontend/src/pages/ApplicationFormPage/components/QuestionContainer/* |
Banner, Popup, PhotoModal, QuestionContainer 등 페이지 컴포넌트의 스타일용 props를 $ 접두사로 변경하고 호출부 업데이트 |
styled-components: Admin 페이지 변경 frontend/src/pages/AdminPage/components/QuestionBuilder/*, frontend/src/pages/AdminPage/tabs/ApplicantsTab/* |
관리자 페이지 관련 styled-components의 props를 $ 접두사로 일괄 변경(예: active→$active, disabled→$disabled, status→$status) 및 사용처 업데이트 |
Mixpanel 초기화 변경 frontend/src/utils/initSDK.ts |
VITE_DISABLE_MIXPANEL 플래그에 따른 mockMixpanel 도입 및 해당 플래그일 때 실제 초기화 회피 로직 추가 |
Sequence Diagram(s)
sequenceDiagram
participant User as 사용자
participant PW as Playwright 브라우저
participant App as Vite 앱
participant MSW as Mock Service Worker
participant API as Mock 핸들러
User->>PW: 메인 페이지 접근
PW->>App: 정적 리소스 / 라우트 요청
PW->>MSW: /api/club/search 요청 (intercept, serialized request)
MSW->>API: 목 응답 반환 (클럽 목록)
PW->>PW: 클럽 카드 클릭 (클라이언트 라우팅)
PW->>MSW: /api/club/{id} 요청 (intercept)
MSW->>API: 목 응답 반환 (클럽 상세)
PW->>MSW: /api/club/{id}/apply GET 요청 (intercept)
MSW->>API: 목 응답 반환 (폼 목록/폼 데이터)
User->>PW: 폼 입력 및 제출
PW->>MSW: /api/club/{id}/apply POST 요청 (serializeRequest 포함)
MSW->>API: 목 제출 응답 반환
PW->>PW: 제출 완료 후 상세로 복귀
Estimated code review effort
🎯 4 (Complex) | ⏱️ ~45 minutes
Possibly related issues
- [feature] MOA-591 지원하기 e2e 테스트 추가 #1131: Main changes add a Playwright E2E "apply" test — PR의 E2E 테스트 및 목 데이터 추가 목표와 직접 일치합니다.
- MOA-591: 지원하기 E2E 테스트 추가 요청 — 본 PR이 해당 이슈의 구현(지원하기 플로우 E2E 테스트)을 충족합니다.
Possibly related PRs
- [feature] 동아리 지원서 타입 설계 및 Mock API 개발 #418: mockServiceWorker 관련 직렬화/메시지 포맷 변경과 직접 연관된 PR입니다.
- [fix] styled-components unknown prop warning 제거 #377: styled-components의 비-DOM prop을
$접두사로 리네이밍한 패턴과 중복되는 변경을 포함합니다. - [fix] Mixpanel 초기화 로직 방어 코드 추가 #1008: initSDK/믹스패널 초기화 관련 방어적 변경과 코드 영역이 겹칩니다.
Suggested reviewers
- lepitaaar
- oesnuj
- suhyun113
🚥 Pre-merge checks | ✅ 3 | ❌ 2
❌ Failed checks (2 warnings)
| Check name | Status | Explanation | Resolution |
|---|---|---|---|
| Out of Scope Changes check | PR의 일부 변경사항(ClubTag, CustomTextArea, Header, InputField, QuestionBuilder, ApplicantsTab, PhotoModal, Banner, Popup의 styled-components 프로퍼티 이름 변경 등)이 E2E 테스트 추가 범위를 벗어나 있습니다. | 스타일 컴포넌트 프로퍼티 이름 변경(non-DOM props 접두사 추가)과 관련된 변경사항을 별도의 리팩토링 PR로 분리하세요. E2E 테스트 구현에만 집중하세요. | |
| Docstring Coverage | Docstring coverage is 63.64% which is insufficient. The required threshold is 80.00%. | Write docstrings for the functions missing them to satisfy the coverage threshold. |
✅ Passed checks (3 passed)
| Check name | Status | Explanation |
|---|---|---|
| Description Check | ✅ Passed | Check skipped - CodeRabbit’s high-level summary is enabled. |
| Title check | ✅ Passed | PR 제목 '[test] 지원하기 e2e 테스트'는 주요 변경사항인 지원하기(apply) 플로우에 대한 E2E 테스트 추가를 명확하게 요약합니다. |
| Linked Issues check | ✅ Passed | MOA-591 이슈의 목표인 '지원하기 e2e 테스트 추가'가 PR의 모든 변경사항으로 충족됩니다: Playwright 설정, 테스트 구성, mock 데이터, apply-flow 테스트 스펙이 구현되었습니다. |
✏️ Tip: You can configure your own custom pre-merge checks in the settings.
✨ Finishing touches
🧪 Generate unit tests (beta)
- Create PR with unit tests
- Post copyable unit tests in a comment
- Commit unit tests in branch
feature/#1131-apply-e2e-test-MOA-591
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.
Comment @coderabbitai help to get the list of available commands and usage tips.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
🤖 Fix all issues with AI agents
In `@frontend/e2e/apply-flow.spec.ts`:
- Around line 96-104: Replace the flaky text-regex assertion by explicitly
waiting for the /api/club/search response and then asserting the presence of a
known club card from the mock data (e.g., "테스트 동아리"); specifically, after
calling page.goto('/') and closePopupIfExists(page), call Playwright's
response-waiting (e.g., page.waitForResponse that matches '/api/club/search') to
ensure the search API completed, then replace expect(page.getByText(/전체 \d+개의
동아리/)) with an assertion that the club card element for "테스트 동아리" (using
page.getByText("테스트 동아리") or the card selector used in the test suite) is
visible.
- Around line 52-58: The URL matching in the request handler is too brittle
because it uses string includes and a negative includes check; update the logic
in the handler that currently checks
url.includes(`/api/club/${MOCK_CLUB_ID}/apply`) && !url.includes(`/apply/`) to
instead parse the request URL (e.g., const pathname = new URL(url).pathname) and
compare pathname === `/api/club/${MOCK_CLUB_ID}/apply`; when matched, continue
to call route.fulfill with mockApplicationOptionsResponse as before. This change
should be applied where MOCK_CLUB_ID, mockApplicationOptionsResponse, and
route.fulfill are used so the GET /api/club/{clubId}/apply matching is based on
pathname not raw URL string.
In `@frontend/src/index.tsx`:
- Around line 15-24: Currently the code blindly unregisters all service workers
via navigator.serviceWorker.getRegistrations() and
registrations.map(...unregister()), which can remove non-MSW workers; instead,
filter registrations to only target MSW's worker by checking each registration's
scriptURL or active?.scriptURL for the MSW filename (e.g., "mockServiceWorker"
or the configured MSW script name) and only call unregister() on those matches;
update the logic around navigator.serviceWorker.getRegistrations(), the
registrations.map/unregister call, and any surrounding DEV + disableMsw guard to
perform this filtered-unregister behavior.
🧹 Nitpick comments (5)
frontend/src/pages/ClubDetailPage/components/PhotoModal/PhotoModal.styles.ts (1)
203-218: LGTM!$isActive트랜지언트 prop 변경이 적절합니다.하드코딩된
#ddd색상이 있습니다. 일관성을 위해 테마 색상 사용을 고려해 보세요.🎨 테마 색상 사용 제안
&:hover { border-color: ${({ $isActive }) => - $isActive ? colors.primary[900] : '#ddd'}; + $isActive ? colors.primary[900] : colors.gray[400]}; }frontend/src/pages/AdminPage/tabs/ApplicantsTab/ApplicantsTab.styles.ts (1)
341-357: 상태 문자열 하드코딩에 대한 유지보수 고려사항.
$status트랜지언트 prop 변경은 올바르지만, 스타일 로직에 한글 상태 문자열('서류검토','면접예정','합격','불합')이 직접 하드코딩되어 있습니다. 상태 값이 변경되면 여러 곳을 수정해야 할 수 있습니다.향후 유지보수를 위해 상수나 매핑 객체 사용을 고려해 보세요.
♻️ 상수 사용 제안 예시
// 상태별 스타일 매핑 상수 정의 const STATUS_STYLES = { 서류검토: { background: '#E6F4FB', color: '#222' }, 면접예정: { background: '#E6FBF0', color: '#222' }, 합격: { background: '#F5F5F5', color: '#888' }, 불합: { background: '#FFE8E8', color: '#222' }, default: { background: '#eee', color: '#222' }, } as const; // 사용 예시 export const ApplicantStatusBadge = styled.span<{ $status: string }>` ... background: ${({ $status }) => STATUS_STYLES[$status]?.background ?? STATUS_STYLES.default.background}; color: ${({ $status }) => STATUS_STYLES[$status]?.color ?? STATUS_STYLES.default.color}; `;.github/workflows/front-test.yml (1)
90-96: Playwright report 업로드 경로 생성 보장 필요CI에서 reporter가
github만이면playwright-report/가 생성되지 않아 업로드 단계가 경고/실패할 수 있습니다. HTML reporter 추가 또는 업로드 단계의if-no-files-found처리 중 하나를 권장합니다.🧩 업로드 단계에서 누락 허용
- name: Upload Playwright report uses: actions/upload-artifact@v4 if: always() with: name: playwright-report path: frontend/playwright-report/ retention-days: 7 + if-no-files-found: ignorefrontend/e2e/apply-flow.spec.ts (2)
11-28: 중복 헬퍼는 공통 유틸로 추출 권장
main-page.spec.ts와 동일한closePopupIfExists가 중복되어 유지보수 비용이 커집니다. 공통 유틸로 분리해 import하는 쪽이 안정적입니다.
108-110: toHaveURL은 정규식 대신 문자열 매칭으로 단순화 권장MOCK 상수 기반이라 위험도는 낮지만, 정규식 생성 경고가 계속 남습니다.
toHaveURL에 문자열을 넘기면 경고 제거 + 가독성 향상 효과가 있습니다.🔧 제안 수정안
- await expect(page).toHaveURL(new RegExp(`/clubDetail/${MOCK_CLUB_ID}`), { + await expect(page).toHaveURL(`/clubDetail/${MOCK_CLUB_ID}`, { timeout: 10000, }); - await expect(page).toHaveURL( - new RegExp(`/application/${MOCK_CLUB_ID}/${MOCK_FORM_ID}`), - { timeout: 10000 }, - ); + await expect(page).toHaveURL( + `/application/${MOCK_CLUB_ID}/${MOCK_FORM_ID}`, + { timeout: 10000 }, + ); - await expect(page).toHaveURL(new RegExp(`/clubDetail/${MOCK_CLUB_ID}`), { + await expect(page).toHaveURL(`/clubDetail/${MOCK_CLUB_ID}`, { timeout: 10000, });Also applies to: 123-125, 153-155
| } else if ( | ||
| import.meta.env.DEV && | ||
| disableMsw && | ||
| 'serviceWorker' in navigator | ||
| ) { | ||
| // 남아 있는 MSW 서비스워커가 e2e 실행에 영향을 주지 않도록 정리 | ||
| const registrations = await navigator.serviceWorker.getRegistrations(); | ||
| await Promise.all( | ||
| registrations.map((registration) => registration.unregister()), | ||
| ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MSW 비활성화 시 모든 서비스워커 제거는 과도합니다
VITE_DISABLE_MSW=true일 때 전체 등록을 해제하면 MSW 외 다른 서비스워커까지 제거될 수 있어 dev 동작이 깨질 수 있습니다. MSW 워커만 필터링해서 해제하는 쪽이 안전합니다.
🔧 MSW 워커만 해제하도록 필터링
- const registrations = await navigator.serviceWorker.getRegistrations();
- await Promise.all(
- registrations.map((registration) => registration.unregister()),
- );
+ const registrations = await navigator.serviceWorker.getRegistrations();
+ const mswRegistrations = registrations.filter((registration) =>
+ [registration.active, registration.waiting, registration.installing].some(
+ (sw) => sw?.scriptURL.includes('mockServiceWorker.js'),
+ ),
+ );
+ await Promise.all(mswRegistrations.map((r) => r.unregister()));🤖 Prompt for AI Agents
In `@frontend/src/index.tsx` around lines 15 - 24, Currently the code blindly
unregisters all service workers via navigator.serviceWorker.getRegistrations()
and registrations.map(...unregister()), which can remove non-MSW workers;
instead, filter registrations to only target MSW's worker by checking each
registration's scriptURL or active?.scriptURL for the MSW filename (e.g.,
"mockServiceWorker" or the configured MSW script name) and only call
unregister() on those matches; update the logic around
navigator.serviceWorker.getRegistrations(), the registrations.map/unregister
call, and any surrounding DEV + disableMsw guard to perform this
filtered-unregister behavior.
- e2e 환경에서 SW 등록 오류 방지)
- e2e/CI 환경에서 트래킹 호출 안전 처리
#️⃣연관된 이슈
📝작업 내용
중점적으로 리뷰받고 싶은 부분(선택)
논의하고 싶은 부분(선택)
🫡 참고사항
Summary by CodeRabbit
릴리스 노트
Tests
Chores
Ignore
✏️ Tip: You can customize this high-level summary in your review settings.