- 모바일 중심으로 개선된 UI가 상태/권한 분기에서 깨지지 않고 일관되게 동작하는지 검증한다.
- 기능 회귀(버튼 활성 조건, 오버레이 노출 조건, 기본 렌더 흐름)를 테스트로 고정한다.
- 대상:
src/components/AppShell.tsx,src/pages/Dashboard.tsx,src/pages/MemberRegistration.tsx,src/pages/Attendance.tsx,src/pages/TermTransition.tsx,src/App.tsx - 제외: 실제 온체인 트랜잭션 성공/실패의 체인 레벨 검증(E2E 단계에서 별도)
- 유닛 테스트 (작은 단위)
- 각 페이지/컴포넌트의 조건부 렌더링과 버튼 상태 검증
- 훅/외부 의존성은 목킹
- 통합 테스트 (중간~큰 단위)
- 라우팅 + 셸 + 페이지 결합 동작 검증
- 연결 상태에 따른 리다이렉트/메뉴/페이지 접근성 검증
@mysten/dapp-kituseCurrentAccountuseSuiClientQueryConnectButton(더미 컴포넌트)
src/networkConfig.tsuseNetworkVariable
- 내부 훅
useBlockblockIdsuseBlockblockObjectsuseRolesuseBlockblockTx
accountConnected:{ address: "0x1234..." }accountDisconnected:nullidsDefault: 필수 id 존재, 레지스트리 id는 케이스별 주입clubDefault: term/roles/member list/attendance_sheets 포함rolesPresident,rolesVice,rolesMember,rolesExternal
- Mobile: width 375
- Desktop: width 1280
- 목표: 모바일 기준으로 주요 텍스트/버튼이 DOM에 존재하고 접근 가능해야 함
account가 없으면 메뉴 대신 안내문이 노출된다.account가 있으면 4개 메뉴(Dashboard, Member Registration, Attendance, Term Transition)가 보인다.- "운영 가이드 보기" 클릭 시 모달이 열리고, "닫기" 클릭 시 닫힌다.
- 모바일 뷰포트에서 메뉴 버튼들이 렌더되고 클릭 가능하다.
- 내 정보 박스에 기수/역할 라벨이 올바르게 표시된다(회장/부회장/총무/운영진/일반부원/외부인).
- 지갑 미연결이면
Landing + NotConnected가 노출된다. - 지갑 연결 상태에서
/접근 시/dashboard로 리다이렉트된다. - 미정의 경로 접근 시
/dashboard로 리다이렉트된다.
- 클럽 정보(기수, 활동 여부, Club ID, 회장/부회장/총무)가 렌더된다.
clubQuery.isPending이면 "불러오는 중" 배지가 노출된다.clubQuery.isError이면 "조회 실패" 배지가 노출된다.attendance_sheets가 비어있으면 "등록된 출석 시트가 없습니다."가 노출된다.attendance_sheets가 있으면 세션 라벨(정기 세션/오리엔테이션 등) 변환 결과가 노출된다.details펼침 시 출석/지각/결석/병결 목록이 노출된다.- 하단
필수 Object IDs 보기토글 시IdsPanel이 렌더된다.
- 회장이 아닐 때 운영진 등록 영역 위 오버레이 문구가 노출된다.
- 회장일 때 "레지스트리 생성" 버튼이 활성화된다.
memberRegistryId가 없으면 "등록 요청 제출" 버튼이 비활성화된다.- 멤버 요청 리스트가 비어있으면 빈 상태 문구가 노출된다.
- 멤버 요청 리스트가 있으면 주소/신입여부/이름/전공이 표시된다.
- 운영진 주소 Select에 클럽 멤버가 없는 경우 "없음" 항목이 노출된다.
attendanceRegistryId가 없으면 상단에 "생성 전" 상태가 노출된다.attendanceFields.is_open === true면 "Open" 배지가 노출된다.attendanceFields.is_open === false면 "Closed" 배지가 노출된다.- 회장이 아닐 때
attendanceRegistryId가 없으면 "지금은 출석할 수 없어요." 오버레이가 노출된다. - 회장이 아닐 때
attendanceRegistryId가 있고is_open === false면 "출석이 마감되었습니다." 오버레이가 노출된다. - 회장일 때만 "출석 레지스트리 생성", "출석 마감", "출석 시트 저장" 액션 영역이 렌더된다.
- 출석/지각/결석/병결 목록에 member_address가 노출된다.
is_open === false일 때 "출석 등록" 버튼이 비활성화된다.is_open !== false일 때 상태 등록(지각/결석/병결) 버튼이 비활성화된다.
closingRegistryId없고club.is_active === true면 "생성 전"이 노출된다.club.is_active === false이고closingRegistryId없으면 "마감 완료"가 노출된다.- 종료 투표 상태 배지(회장/부회장/총무)가 true/false에 따라 표시된다.
- 전환 레지스트리 id/다음 회장 주소가 표시된다.
- 회장이 아닐 때 "다음 기수 전환 레지스트리 생성" 버튼이 비활성화된다.
- 전환 투표 3개가 모두 true가 아니면 "다음 기수 생성" 버튼이 비활성화된다.
- 지갑 연결 상태에서 메뉴 클릭 시 경로 전환이 정상 동작한다.
/dashboard->/members->/attendance->/transition
- 모바일 뷰포트에서 메뉴 클릭으로 각 페이지에 진입 가능하다.
- Dashboard의 IDs 토글 확인 후 Members 페이지로 이동한다.
- Members에서
memberRegistryId유무에 따라 버튼 상태가 즉시 반영된다(동일 ids fixture 공유 기준).
is_open: true상태에서는 출석 등록 영역이 활성/오버레이 미노출.- 같은 테스트에서 상태를
is_open: false로 바꿔 rerender 시:
- 출석 등록 버튼 비활성
- 비회장 오버레이 노출
- 상태 등록 버튼 활성 조건이 바뀌는지 확인
closingRegistry투표 상태를 false->true로 바꿔 rerender 시 종료 버튼 활성 조건이 바뀐다.transitionRegistry투표 3개가 모두 true일 때만 실행 버튼이 활성화된다.
account: null에서 시작해 연결 상태 fixture로 rerender하면 Landing/NotConnected에서 라우트 페이지로 전환된다.- 연결 해제 시 다시 Landing/NotConnected로 복귀한다.
- App 연결/라우팅 분기
- Attendance 오버레이 + 버튼 활성 조건
- TermTransition 투표 기반 버튼 활성 조건
- MemberRegistration 회장 권한 오버레이
- Dashboard 출석 시트 렌더/세션 라벨 변환
- AppShell 모달 열기/닫기
- 모바일/데스크탑 viewport 스냅샷 테스트
- 긴 주소 문자열 표시 회귀 테스트
- P0 테스트 100% 통과
- P1 테스트 통과
- CI 환경에서
pnpm run build+ 테스트 통과 - 모바일 뷰포트(375)에서 핵심 액션 버튼/문구 DOM 존재 검증 완료
- 테스트 유틸/공통 fixture 구축
- App/AppShell 테스트 작성
- 페이지별 P0 테스트 작성 (
Attendance,TermTransition,MemberRegistration) Dashboard테스트 작성- 통합 시나리오 작성
- 마지막으로 viewport/스냅샷 보강