-
Notifications
You must be signed in to change notification settings - Fork 155
[2단계 - 영화 목록 불러오기] 라바 미션 제출합니다. #303
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: kojesung
Are you sure you want to change the base?
Changes from all commits
9f0c0c8
44ef190
18bd7d4
0e76463
f5b3b80
1818cce
cd41299
4e8951f
971e972
8d67a70
9cae087
8c410f1
6c8bf98
87b2bb5
5ea6373
6972e6f
33bcec4
063162a
3d795b9
f730e37
9fe3c54
c4c9026
1c32529
0e55c8b
ac4e310
85f7166
3b81fae
2c53fbb
68687a9
065cafe
2d02303
d955370
212dad7
ceb199f
e99eb22
f19f851
9af1055
5a9ad1e
8e5f36c
b0ec7d3
90caada
0838ea1
cfc3fdf
f87e882
7ad48fe
1cc3d63
417dd03
9e7edff
ef84766
f09a5ba
04b0cbd
559dfdf
4ff24af
95ce7d8
58d748f
46a7a51
c2a6a00
d788fbc
d21b705
bfde8e4
aee600f
537b255
d995a59
e8e21d1
9982917
3f616e8
73dd1a3
5ae53f1
73f0014
8e060ef
19c8538
2620717
ad6225a
57e0ac6
2edb92a
c872de9
1a72a45
e074a72
1782643
b829bfa
17ee5f0
3ebd2e2
7b00482
f631959
f2bab66
dcde1b5
9215199
b5c2254
f3e04db
1947027
140a004
b003897
3b28260
c5c6d41
f468fa8
84e0e0f
fcdb398
8d5542c
024b4e3
d992906
ca9731e
d6900f5
5109e6d
a7afd66
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 |
|---|---|---|
| @@ -0,0 +1,125 @@ | ||
| import { | ||
| interceptPopularPage1, | ||
| interceptMovieDetail, | ||
| interceptMovieDetailWithDelay, | ||
| } from "./spec"; | ||
|
|
||
| describe("모달", () => { | ||
|
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. 스켈레톤 표시, 데이터 렌더링, 닫기(X/배경/ESC), 별점 유지까지. 모달 E2E 테스트가 매우 꼼꼼하네요👍 |
||
| beforeEach(() => { | ||
| interceptPopularPage1(); | ||
| cy.visit("/"); | ||
| cy.wait("@getPopularPage1"); | ||
| }); | ||
|
|
||
| it("썸네일 클릭 시 모달이 열린다", () => { | ||
| interceptMovieDetail(); | ||
| cy.get("li[id^='movie-']").first().click(); | ||
| cy.get("#modalBackground").should("not.have.class", "hidden"); | ||
| }); | ||
|
|
||
| it("모달이 열리면 API 응답 전 스켈레톤이 표시된다", () => { | ||
| interceptMovieDetailWithDelay(500); | ||
| cy.get("li[id^='movie-']").first().click(); | ||
| cy.get("#modal-title").should("have.class", "modal-skeleton"); | ||
| cy.get("#modal-category").should("have.class", "modal-skeleton"); | ||
| cy.get("#modal-rate").should("have.class", "modal-skeleton"); | ||
| cy.get("#modal-detail").should("have.class", "modal-skeleton"); | ||
| }); | ||
|
|
||
| it("API 응답 후 영화 정보가 렌더링된다", () => { | ||
| interceptMovieDetail(); | ||
| cy.get("li[id^='movie-']").first().click(); | ||
| cy.wait("@getMovieDetail"); | ||
| cy.get("#modal-title").should("contain.text", "영화1"); | ||
| cy.get("#modal-category") | ||
| .should("contain.text", "2024") | ||
| .and("contain.text", "액션"); | ||
| cy.get("#modal-rate").should("contain.text", "8.0"); | ||
| cy.get("#modal-detail").should("contain.text", "줄거리1"); | ||
| }); | ||
|
|
||
| it("API 응답 후 스켈레톤이 제거된다", () => { | ||
| interceptMovieDetail(); | ||
| cy.get("li[id^='movie-']").first().click(); | ||
| cy.wait("@getMovieDetail"); | ||
| cy.get("#modal-title").should("not.have.class", "modal-skeleton"); | ||
| cy.get("#modal-category").should("not.have.class", "modal-skeleton"); | ||
| cy.get("#modal-rate").should("not.have.class", "modal-skeleton"); | ||
| cy.get("#modal-detail").should("not.have.class", "modal-skeleton"); | ||
| }); | ||
|
|
||
| describe("모달 닫기", () => { | ||
| beforeEach(() => { | ||
| interceptMovieDetail(); | ||
| cy.get("li[id^='movie-']").first().click(); | ||
| cy.wait("@getMovieDetail"); | ||
| }); | ||
|
|
||
| it("X 버튼 클릭 시 모달이 닫힌다", () => { | ||
| cy.get("#closeModal").click(); | ||
| cy.get("#modalBackground").should("have.class", "hidden"); | ||
| }); | ||
|
|
||
| it("배경 클릭 시 모달이 닫힌다", () => { | ||
| cy.get("#modalBackground").click({ force: true }); | ||
| cy.get("#modalBackground").should("have.class", "hidden"); | ||
| }); | ||
|
|
||
| it("ESC 키 입력 시 모달이 닫힌다", () => { | ||
| cy.get("body").type("{esc}"); | ||
| cy.get("#modalBackground").should("have.class", "hidden"); | ||
| }); | ||
| }); | ||
|
|
||
| describe("별점", () => { | ||
| beforeEach(() => { | ||
| interceptMovieDetail(); | ||
| cy.get("li[id^='movie-']").first().click(); | ||
| cy.wait("@getMovieDetail"); | ||
| }); | ||
|
|
||
| it("별을 클릭하면 해당 별까지 채워진다", () => { | ||
| cy.get("#modal-my-rate-star-3").click(); | ||
| cy.get("#modal-my-rate-star-1") | ||
| .should("have.attr", "src") | ||
| .and("include", "star_filled"); | ||
| cy.get("#modal-my-rate-star-2") | ||
| .should("have.attr", "src") | ||
| .and("include", "star_filled"); | ||
| cy.get("#modal-my-rate-star-3") | ||
| .should("have.attr", "src") | ||
| .and("include", "star_filled"); | ||
| cy.get("#modal-my-rate-star-4") | ||
| .should("have.attr", "src") | ||
| .and("include", "star_empty"); | ||
| cy.get("#modal-my-rate-star-5") | ||
| .should("have.attr", "src") | ||
| .and("include", "star_empty"); | ||
| }); | ||
|
|
||
| it("별을 클릭하면 별점 레이블이 변경된다", () => { | ||
| cy.get("#modal-my-rate-star-3").click(); | ||
| cy.get("#modal-rate-review").should("contain.text", "보통이에요"); | ||
| cy.get("#modal-rate-points").should("contain.text", "6/10"); | ||
| }); | ||
|
|
||
| it("모달을 닫고 다시 열어도 별점이 유지된다", () => { | ||
| cy.get("#modal-my-rate-star-4").click(); | ||
| cy.get("#closeModal").click(); | ||
|
|
||
| interceptMovieDetail(); | ||
| cy.get("li[id^='movie-']").first().click(); | ||
| cy.wait("@getMovieDetail"); | ||
|
|
||
| cy.get("#modal-my-rate-star-1") | ||
| .should("have.attr", "src") | ||
| .and("include", "star_filled"); | ||
| cy.get("#modal-my-rate-star-4") | ||
| .should("have.attr", "src") | ||
| .and("include", "star_filled"); | ||
| cy.get("#modal-my-rate-star-5") | ||
| .should("have.attr", "src") | ||
| .and("include", "star_empty"); | ||
| }); | ||
| }); | ||
| }); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| { | ||
| "id": 1, | ||
| "title": "영화1", | ||
| "poster_path": "/poster1.jpg", | ||
| "backdrop_path": "/back1.jpg", | ||
| "vote_average": 8.0, | ||
| "overview": "줄거리1 상세 설명입니다.", | ||
| "release_date": "2024-01-01", | ||
| "genres": [ | ||
| { "id": 28, "name": "액션" }, | ||
| { "id": 12, "name": "어드벤처" } | ||
| ], | ||
| "adult": false, | ||
| "belongs_to_collection": null, | ||
| "budget": 0, | ||
| "homepage": "", | ||
| "imdb_id": "tt0000001", | ||
| "origin_country": ["KR"], | ||
| "original_language": "ko", | ||
| "original_title": "Movie1", | ||
| "popularity": 100, | ||
| "production_companies": [], | ||
| "production_countries": [], | ||
| "revenue": 0, | ||
| "runtime": 120, | ||
| "spoken_languages": [], | ||
| "status": "Released", | ||
| "tagline": "", | ||
| "video": false, | ||
| "vote_count": 1000 | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,14 +6,15 @@ | |
| <link rel="stylesheet" href="./styles/reset.css" /> | ||
| <link rel="stylesheet" href="./styles/main.css" /> | ||
| <link rel="stylesheet" href="./styles/thumbnail.css" /> | ||
| <link rel="stylesheet" href="./styles/modal.css" /> | ||
| <title>영화 리뷰</title> | ||
| </head> | ||
| <body> | ||
| <div id="app"> | ||
| <header> | ||
| <div class="logo-input-wrapper"> | ||
| <button class="logo" id="logo"> | ||
| <img src="./public/images/logo.png" alt="MovieList" /> | ||
| <img src="./images/logo.png" alt="MovieList" /> | ||
| </button> | ||
| <div class="movie-search"> | ||
| <input | ||
|
|
@@ -23,7 +24,7 @@ | |
| autocomplete="off" | ||
| /> | ||
| <button id="search-button"> | ||
| <img src="./public/images/search.png" alt="검색" /> | ||
| <img src="./images/search.png" alt="검색" /> | ||
| </button> | ||
| </div> | ||
| </div> | ||
|
|
@@ -32,7 +33,7 @@ | |
| <div class="top-rated-container"> | ||
| <div class="top-rated-movie"> | ||
| <div class="rate"> | ||
| <img src="./public/images/star_empty.png" class="star" /> | ||
| <img src="./images/star_empty.png" class="star" /> | ||
| <span class="rate-value"></span> | ||
| </div> | ||
| <h3 class="title"></h3> | ||
|
|
@@ -48,7 +49,7 @@ <h2 class="sub-title" id="sub-title">지금 인기 있는 영화</h2> | |
|
|
||
| <ul class="thumbnail-list hidden" id="main-thumbnail-list"></ul> | ||
| <ul class="thumbnail-list hidden" id="search-thumbnail-list"></ul> | ||
|
|
||
| <div id="main-error-container"></div> | ||
| <ul class="thumbnail-list hidden" id="skeleton-list"> | ||
| <li class="skeleton"> | ||
| <div class="item"> | ||
|
|
@@ -188,12 +189,12 @@ <h2 class="sub-title" id="sub-title">지금 인기 있는 영화</h2> | |
| </ul> | ||
|
|
||
| <div class="unexpected-container hidden" id="empty-container"> | ||
| <img src="./public/images/으아아행성이.png" alt="" /> | ||
| <img src="./images/으아아행성이.png" alt="" /> | ||
| <p>검색 결과가 없습니다.</p> | ||
| </div> | ||
|
|
||
| <div class="unexpected-container hidden" id="error-container"> | ||
| <img src="./public/images/으아아행성이.png" alt="" /> | ||
| <img src="./images/으아아행성이.png" alt="" /> | ||
| <p>🚨 에러 발생 🚨</p> | ||
| <button>재시도</button> | ||
| </div> | ||
|
|
@@ -207,14 +208,88 @@ <h2 class="sub-title" id="sub-title">지금 인기 있는 영화</h2> | |
| </section> | ||
| </main> | ||
| </div> | ||
|
|
||
| <div id="sentinel"></div> | ||
| <footer class="footer"> | ||
| <p>© 우아한테크코스 All Rights Reserved.</p> | ||
| <p> | ||
| <img src="./public/images/woowacourse_logo.png" width="180" /> | ||
| <img src="./images/woowacourse_logo.png" width="180" /> | ||
| </p> | ||
| </footer> | ||
| </div> | ||
| <div class="modal-background active" id="modalBackground"> | ||
| <div class="modal" id="modal"> | ||
| <button class="close-modal" id="closeModal"> | ||
| <img src="./images/modal_button_close.png" /> | ||
| </button> | ||
|
Comment on lines
+221
to
+223
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. 닫기 버튼에 접근 가능한 이름을 넣어 주세요. 아이콘만 들어 있는 버튼인데 텍스트나 🤖 Prompt for AI Agents |
||
| <div class="modal-container"> | ||
| <div class="modal-image modal-skeleton-image" id="modal-image"> | ||
| <img src="" alt="" /> | ||
|
Comment on lines
+225
to
+226
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. 🧩 Analysis chain🏁 Script executed: # First, let's check the index.html file around lines 225-226
head -n 230 index.html | tail -n 20Repository: woowacourse/javascript-movie-review Length of output: 821 🏁 Script executed: # Check if there's a linting configuration in the repository
find . -maxdepth 2 -type f \( -name ".eslintrc*" -o -name "eslintignore" -o -name ".htmlhintrc" -o -name "w3crc" -o -name "prettier*" \)Repository: woowacourse/javascript-movie-review Length of output: 109 🏁 Script executed: # Search for JavaScript that sets the modal image src
rg "modal-image|modal.*src|querySelector.*modal" -A 3 -B 1Repository: woowacourse/javascript-movie-review Length of output: 2356 🏁 Script executed: # Check .htmlhintrc configuration
cat .htmlhintrcRepository: woowacourse/javascript-movie-review Length of output: 232 🏁 Script executed: # Check .eslintrc.json configuration
cat .eslintrc.jsonRepository: woowacourse/javascript-movie-review Length of output: 268 🏁 Script executed: # Check if there are any other relevant files related to linting
rg "src=\"\"" index.htmlRepository: woowacourse/javascript-movie-review Length of output: 112 🌐 Web query:
💡 Result: An empty src attribute on an <img> tag (src="") triggers a network request to the current document's URL in most browsers, potentially causing performance issues, traffic spikes, or state corruption via cookies/sessions. This is due to URI resolution treating "" as a relative path resolving to the base URL per RFC 3986. Key browser behaviors (historical and recent sources up to 2026): - Chrome/Safari/WebKit: Requests the page itself. - Firefox: Fixed in 3.5+ (no request). - IE: Requests the page directory. - Opera: Ignores. HTML spec requires non-empty valid URL for src; empty src shows broken image icon but still fetches in many engines. Recent WHATWG issues (2026) discuss extending no-fetch to whitespace-only src to match Chromium/WebKit interop. No full document reload occurs; it's an additional subresource request visible in Network tab (test: open DevTools Network, load <img src="">). Use data URI, about:blank, or omit src/JS-set later to avoid. Workarounds: - src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" - Omit src, set via JS: img.src = "image.jpg" - Transparent 1x1 placeholder. To verify: Chrome DevTools Network tab shows the request when loading <img src="">. Citations:
🧰 Tools🪛 HTMLHint (1.9.2)[error] 226-226: The attribute [ src ] of the tag [ img ] must have a value. (src-not-empty) 🤖 Prompt for AI Agents |
||
| </div> | ||
| <div class="modal-description" id="modal-description"> | ||
| <div class="modal-header"> | ||
| <h2 | ||
| id="modal-title" | ||
| class="modal-skeleton modal-skeleton-title" | ||
| ></h2> | ||
| <p | ||
| id="modal-category" | ||
| class="modal-skeleton modal-skeleton-category" | ||
| ></p> | ||
| <p class="rate"> | ||
| <img src="./images/star_filled.png" class="star" /><span | ||
| id="modal-rate" | ||
| class="modal-skeleton modal-skeleton-rate" | ||
| ></span> | ||
| </p> | ||
| </div> | ||
| <hr /> | ||
| <h3 id="modal-my-rate" class="modal-sub-title">내 별점</h3> | ||
| <p id="modal-rate-stars" class="modal-rate-stars"> | ||
| <img | ||
| src="./images/star_empty.png" | ||
| class="modal-my-rate-star" | ||
| id="modal-my-rate-star-1" | ||
| /> | ||
| <img | ||
| src="./images/star_empty.png" | ||
| class="modal-my-rate-star" | ||
| id="modal-my-rate-star-2" | ||
| /> | ||
| <img | ||
| src="./images/star_empty.png" | ||
| class="modal-my-rate-star" | ||
| id="modal-my-rate-star-3" | ||
| /> | ||
| <img | ||
| src="./images/star_empty.png" | ||
| class="modal-my-rate-star" | ||
| id="modal-my-rate-star-4" | ||
| /> | ||
| <img | ||
| src="./images/star_empty.png" | ||
| class="modal-my-rate-star" | ||
| id="modal-my-rate-star-5" | ||
| /> | ||
| <span> | ||
| <span class="modal-rate-review" id="modal-rate-review" | ||
| >명작이에요</span | ||
| > | ||
| <span class="modal-rate-points" id="modal-rate-points" | ||
| >(8/10)</span | ||
| ></span | ||
| > | ||
| </p> | ||
| <hr /> | ||
| <h3 id="modal-detail-title" class="modal-sub-title">줄거리</h3> | ||
| <p | ||
| class="detail" | ||
| id="modal-detail" | ||
| class="modal-skeleton modal-skeleton-detail" | ||
| ></p> | ||
|
Comment on lines
+284
to
+288
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. 🧩 Analysis chain🏁 Script executed: find . -name "index.html" -type fRepository: woowacourse/javascript-movie-review Length of output: 91 🏁 Script executed: sed -n '280,290p' ./index.htmlRepository: woowacourse/javascript-movie-review Length of output: 388
동일 요소에 🤖 Prompt for AI Agents |
||
| </div> | ||
| </div> | ||
| </div> | ||
| </div> | ||
| <script type="module" src="./src/main.ts"></script> | ||
| </body> | ||
| </html> | ||
|
|
||
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.
용어 오탈자 수정이 필요합니다
localsStorage→localStorage로 수정하는 편이 문서 신뢰성과 검색성을 높입니다.🤖 Prompt for AI Agents