-
Notifications
You must be signed in to change notification settings - Fork 155
[2단계 - 상세 정보 & UI/UX 개선하기] 이현 미션 제출합니다. #295
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: jebiyeon02
Are you sure you want to change the base?
Changes from 28 commits
aff9bde
8afc143
f9175d4
e31a537
a067fb1
b51762d
19daf40
53460c9
dcb58c5
78f8287
410554b
0f09f50
8e830c1
ddd6492
8d6a258
b47dc98
f4075df
f45f130
8017394
a11bcc9
1674da4
90ab8fa
17bf0d5
335d514
00fbd2d
253704f
694fac2
5691ddf
de13d76
174b780
53784ba
72e4b4d
2bfff07
b40b7ba
2f34842
ff39f9f
fa1f0b6
7d22598
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,27 +2,48 @@ | |
|
|
||
| FE 레벨1 영화 리뷰 미션 | ||
|
|
||
| 2단계 - 상세 정보 & UI/UX 개선하기 | ||
|
|
||
| # 요구사항 목록 | ||
|
|
||
| ## 1. 검색 | ||
| ## 1. 인기 영화 목록 | ||
|
|
||
| - 인기 영화를 최대 20개 가져온다. | ||
| - **무한스크롤 방식으로 추가 영화를 최대 20개씩 가져온다.** | ||
| - **더이상 가져올 영화가 없으면 스크롤이 끝난다.** | ||
| - 스켈레톤 UI를 표시한다. | ||
|
|
||
| ## 2. 배너 | ||
|
|
||
| - 가장 인기 있는 영화의 정보를 띄운다. | ||
| - 자세히 보기 클릭 시 상세 정보가 표시된다. | ||
|
|
||
| ## 3. 검색 | ||
|
|
||
| - 검색어를 입력받아 검색한다. | ||
| - 검색어에 해당하는 영화를 10개 가져온다. | ||
| - 더보기를 누르면 10개를 추가로 가져온다. | ||
| - 해당하는 모든 영화를 가져왔을 때 더 보기 버튼을 숨긴다. | ||
| - 검색어에 해당하는 영화가 없을 경우, "검색 결과가 없습니다" | ||
| - 검색어에 해당하는 영화를 최대 20개 가져온다. | ||
| - **무한스크롤 방식으로 추가 영화를 최대 20개씩 가져온다.** | ||
| - **더이상 가져올 영화가 없으면 스크롤이 끝난다.** | ||
| - 검색어에 해당하는 영화가 없을 경우, "검색 결과가 없습니다"를 표시한다. | ||
| - 검색 시 스켈레톤 UI를 표시한다. | ||
|
|
||
| ## 2. 영화 목록 | ||
| ## 4. 영화 상세정보 | ||
|
|
||
| - 영화 20개를 가져온다. | ||
| - 더보기를 누르면 20개를 추가로 가져온다. | ||
| - 모든 영화를 가져왔을 때 더 보기 버튼을 숨긴다. | ||
| - 검색 시 스켈레톤 UI를 표시한다. | ||
| - 영화 포스터 클릭시 해당 영화의 상세 정보를 확인할 수 있는 모달이 표시된다. | ||
| - 데스크톱/태블릿/모바일에 모두 대응 가능하도록 반응형 UI로 구현한다. | ||
| - 포스터, 제목, 장르, 평균 별점, 내 별점, 줄거리를 표시한다. | ||
| - 모달은 ESC, 모달 외부 클릭, 모달 내부 닫기버튼을 통해 닫을 수 있다. | ||
|
|
||
| ## 배너 | ||
| ## 5. 별점 | ||
|
|
||
| - 가장 인기 있는 영화의 정보를 띄운다. | ||
| - 영화 상세정보 내부에서 별을 클릭하여 별점을 매긴다. | ||
| - 별은 총 5개, 개당 2점이고 1점 단위는 고려하지 않는다. | ||
| - 별점별 나타나는 텍스트 | ||
| - 2점: 최악이예요 | ||
| - 4점: 별로예요 | ||
| - 6점: 보통이에요 | ||
| - 8점: 재미있어요 | ||
| - 10점: 명작이에요 | ||
|
|
||
| # 테스트 명세 | ||
|
|
||
|
|
@@ -37,16 +58,32 @@ FE 레벨1 영화 리뷰 미션 | |
|
|
||
| 1. 배너에 첫 번째 인기 영화의 정보가 표시된다. | ||
| 2. 최초 진입 시 인기 영화 최대 20개가 표시된다. | ||
| 3. 더 보기 버튼을 누르면 최대 20개가 추가된다. | ||
| 4. 더 이상 보여 줄 영화가 없으면 더 보기 버튼이 사라진다. | ||
| 3. 스크롤을 내리면 무한 스크롤 방식으로 영화가 추가로 최대 20개씩 표시된다. | ||
| 4. 더 이상 보여 줄 영화가 영화를 가져오지 않는다. | ||
|
|
||
| ### 검색 시 | ||
|
|
||
| 1. `인사이드`를 검색하면 제목에 인사이드가 포함된 영화들이 최대 20개 표시된다. | ||
| 2. 더 보기 버튼을 누르면 최대 20개가 추가된다. | ||
| 3. 더 이상 보여줄 영화가 없으면 더 보기 버튼이 사라진다. | ||
| 2. 스크롤을 내리면 무한 스크롤 방식으로 영화가 추가로 최대 20개씩 표시된다. | ||
| 3. 더 이상 보여 줄 영화가 영화를 가져오지 않는다. | ||
| 4. 검색 결과가 없으면 `검색 결과가 없습니다.`를 아이콘과 함께 표시된다. | ||
| 5. 로고를 누르면 메인 화면으로 돌아온다. | ||
|
|
||
| ### 배너 클릭 시 | ||
|
|
||
| 1. 자세히 보기 버튼을 눌러 영화 상세정보 모달창을 띄운다. | ||
|
|
||
| ### 영화 포스터 클릭 시 | ||
|
|
||
| 1. 영화 상세정보 모달창이 표시된다. | ||
| 2. ESC 키를 입력 또는 모달 외부 화면 클릭으로 모달창을 닫을 수 있다. | ||
| 3. 모달 활성화 시 배경화면 스크롤이 비활성화 된다. | ||
|
|
||
| ### 별점 등록 시 | ||
|
|
||
| 1. 영화 상세정보 모달이 활성화 되었을 때 별점이 없다면 별점 없음이 표시된다. | ||
| 2. 1점을 등록하면 해당하는 텍스트와 함께 별 1개만 채워진다. | ||
| 3. 2점을 등록하면 해당하는 텍스트와 함께 별 2개만 채워진다. | ||
| 4. 3점을 등록하면 해당하는 텍스트와 함께 별 3개만 채워진다. | ||
| 5. 4점을 등록하면 해당하는 텍스트와 함께 별 4개만 채워진다. | ||
| 6. 5점을 등록하면 해당하는 텍스트와 함께 별 5개만 채워진다. | ||
|
Comment on lines
+85
to
+89
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 점수 단위 표현이 앞선 규칙과 충돌합니다. Line 40에서 “별 1개 = 2점”으로 정의했는데, Line 85-89는 “1점/2점/3점...”처럼 읽혀 요구사항 해석이 엇갈릴 수 있습니다. 시나리오 문구를 별 개수 기준 또는 2/4/6/8/10 점수 기준으로 맞춰 주세요. 🤖 Prompt for AI Agents |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| # javascript-movie-review | ||
|
|
||
| FE 레벨1 영화 리뷰 미션 | ||
|
|
||
| # 요구사항 목록 | ||
|
|
||
| ## 1. 검색 | ||
|
|
||
| - 검색어를 입력받아 검색한다. | ||
| - 검색어에 해당하는 영화를 10개 가져온다. | ||
| - 더보기를 누르면 10개를 추가로 가져온다. | ||
| - 해당하는 모든 영화를 가져왔을 때 더 보기 버튼을 숨긴다. | ||
| - 검색어에 해당하는 영화가 없을 경우, "검색 결과가 없습니다" | ||
| - 검색 시 스켈레톤 UI를 표시한다. | ||
|
|
||
| ## 2. 영화 목록 | ||
|
|
||
| - 영화 20개를 가져온다. | ||
| - 더보기를 누르면 20개를 추가로 가져온다. | ||
| - 모든 영화를 가져왔을 때 더 보기 버튼을 숨긴다. | ||
| - 검색 시 스켈레톤 UI를 표시한다. | ||
|
|
||
| ## 배너 | ||
|
|
||
| - 가장 인기 있는 영화의 정보를 띄운다. | ||
|
|
||
| # 테스트 명세 | ||
|
|
||
| ## 단위 테스트 | ||
|
|
||
| 1. 인기 있는 영화 목록을 가져온다. | ||
| 2. 검색어에 맞는 영화만 가져온다. | ||
|
|
||
| ## E2E 시나리오 | ||
|
|
||
| ### 최초 진입 시 | ||
|
|
||
| 1. 배너에 첫 번째 인기 영화의 정보가 표시된다. | ||
| 2. 최초 진입 시 인기 영화 최대 20개가 표시된다. | ||
| 3. 더 보기 버튼을 누르면 최대 20개가 추가된다. | ||
| 4. 더 이상 보여 줄 영화가 없으면 더 보기 버튼이 사라진다. | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 문장 내 공백이 비정상적으로 들어가 있습니다. Line 41의 🤖 Prompt for AI Agents |
||
|
|
||
| ### 검색 시 | ||
|
|
||
| 1. `인사이드`를 검색하면 제목에 인사이드가 포함된 영화들이 최대 20개 표시된다. | ||
| 2. 더 보기 버튼을 누르면 최대 20개가 추가된다. | ||
| 3. 더 이상 보여줄 영화가 없으면 더 보기 버튼이 사라진다. | ||
| 4. 검색 결과가 없으면 `검색 결과가 없습니다.`를 아이콘과 함께 표시된다. | ||
| 5. 로고를 누르면 메인 화면으로 돌아온다. | ||
|
|
||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,79 +1,87 @@ | ||
| describe("메인 화면 최초 진입 시나리오 테스트", () => { | ||
| // TMDB API 응답 형식을 생성하는 헬퍼 함수 | ||
| const mockMovies = ( | ||
| count: number, | ||
| titlePrefix: string, | ||
| page: number, | ||
| totalPages: number, | ||
| ) => ({ | ||
| results: Array.from({ length: count }, (_, i) => ({ | ||
| id: i + (page - 1) * 20, | ||
| title: `${titlePrefix} ${i + 1}`, | ||
| id: 1000 + i + (page - 1) * 20, | ||
| title: `${titlePrefix} ${i + 1 + (page - 1) * 20}`, | ||
| poster_path: "/63In39uCc7769Y0667vCInth6Uv.jpg", | ||
| vote_average: 8.5, | ||
| })), | ||
| page: page, | ||
| page, | ||
| total_pages: totalPages, | ||
| }); | ||
|
|
||
| const visitMainPage = () => { | ||
| cy.visit("http://localhost:5173/"); | ||
| }; | ||
|
|
||
| const scrollToBottom = () => { | ||
| cy.scrollTo("bottom"); | ||
| cy.wait(300); | ||
| }; | ||
|
|
||
| beforeEach(() => { | ||
| // 1페이지 호출 모킹 (20개 응답, 총 2페이지가 있다고 가정) | ||
| cy.intercept( | ||
| "GET", | ||
| "**/movie/popular?*page=1*", | ||
| mockMovies(20, "인기 영화", 1, 2), | ||
| ).as("getPopularP1"); | ||
| cy.intercept("GET", "**/movie/popular?*page=1*", (req) => { | ||
| req.reply({ | ||
| delay: 300, | ||
| body: mockMovies(20, "인기 영화", 1, 2), | ||
| }); | ||
| }).as("getPopularP1"); | ||
|
|
||
| // 2페이지 호출 모킹 (마지막 페이지) | ||
| cy.intercept( | ||
| "GET", | ||
| "**/movie/popular?*page=2*", | ||
| mockMovies(20, "인기 영화", 2, 2), | ||
| ).as("getPopularP2"); | ||
|
|
||
| cy.visit("http://localhost:5173/"); | ||
| }); | ||
|
|
||
| it("1. 배너에 첫 번째 인기 영화의 정보가 표시된다.", () => { | ||
| visitMainPage(); | ||
| cy.wait("@getPopularP1"); | ||
|
|
||
| // 리스트의 첫 번째 영화 제목을 가져와서 배너(.title)와 비교 | ||
| cy.get(".thumbnail-list li:first-child", { timeout: 10000 }) | ||
| cy.get(".thumbnail-list li:first-child") | ||
| .find("strong") | ||
| .invoke("text") | ||
| .then((firstMovieTitle) => { | ||
| cy.get(".title").invoke("text").should("eq", firstMovieTitle); | ||
| cy.get(".title").should("have.text", firstMovieTitle); | ||
| }); | ||
| }); | ||
|
|
||
| it("2. 최초 진입 시 인기 영화 최대 20개가 표시된다.", () => { | ||
| cy.wait("@getPopularP1"); | ||
| visitMainPage(); | ||
|
|
||
| // 리스트 아이템 개수 확인 | ||
| cy.get(".movie-skeleton").should("have.length.at.least", 1); | ||
| cy.wait("@getPopularP1"); | ||
| cy.get(".movie-skeleton").should("not.exist"); | ||
| cy.get(".thumbnail-list li").should("have.length", 20); | ||
| }); | ||
|
|
||
| it("3. 더 보기 버튼을 누르면 최대 20개가 추가된다.", () => { | ||
| it("3. 스크롤을 내리면 무한 스크롤 방식으로 영화가 최대 20개씩 추가된다.", () => { | ||
| visitMainPage(); | ||
| cy.wait("@getPopularP1"); | ||
|
|
||
| // 초기 20개 확인 후 버튼 클릭 | ||
| cy.get(".thumbnail-list li").should("have.length", 20); | ||
| cy.get(".more-button").click(); | ||
|
|
||
| scrollToBottom(); | ||
| cy.wait("@getPopularP2"); | ||
|
|
||
| // 추가되어 총 40개가 되었는지 확인 | ||
| cy.get(".thumbnail-list li").should("have.length", 40); | ||
| }); | ||
|
|
||
| it("4. 더 이상 보여줄 영화가 없으면 더 보기 버튼이 사라진다.", () => { | ||
| it("4. 더 이상 보여 줄 영화가 없으면 영화를 가져오지 않는다.", () => { | ||
| visitMainPage(); | ||
| cy.wait("@getPopularP1"); | ||
|
|
||
| // 마지막 페이지(2페이지)를 불러오도록 버튼 클릭 | ||
| cy.get(".more-button").click(); | ||
| scrollToBottom(); | ||
| cy.wait("@getPopularP2"); | ||
| cy.get(".thumbnail-list li").should("have.length", 40); | ||
|
|
||
| scrollToBottom(); | ||
|
|
||
| // 소스 코드 로직(nowPage === totalPages)에 따라 버튼이 숨겨져야 함 | ||
| cy.get(".more-button").should("not.be.visible"); | ||
| cy.get("@getPopularP2.all").should("have.length", 1); | ||
| cy.get(".thumbnail-list li").should("have.length", 40); | ||
| }); | ||
| }); |
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.
평점 문구 오탈자가 있습니다.
Line 42의
최악이예요는 실제 UI/상수 표현과 맞추려면최악이에요로 통일하는 편이 좋습니다.🤖 Prompt for AI Agents