Skip to content

Commit 1c957b7

Browse files
author
hanjung
committed
feat: update cypress, rtl test (pass check chromatic)
1 parent d4a436b commit 1c957b7

11 files changed

Lines changed: 223 additions & 402 deletions

File tree

cypress/e2e/Home.cy.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ describe('필터', () => {
3838
it('카테고리를 "Shoes"로 선택할 경우 해당 카테고리 상품만 나타난다', () => {
3939
cy.findByRole('radio', { name: 'Shoes' }).click();
4040

41+
// ? 명시적인 로딩 검증 과정 추가
42+
cy.findAllByTestId('product-skeleton').should('have.length.greaterThan', 0);
43+
cy.findAllByTestId('product-skeleton').should('not.exist');
44+
4145
cy.findAllByTestId('product-card').each($el => {
4246
cy.wrap($el).findByText('Shoes').should('exist');
4347
});

cypress/e2e/Purchase.cy.js

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,12 @@ describe('배송 정보', () => {
1919
});
2020

2121
it('할인 쿠폰을 선택하지 않은 경우 "없음"이 노출되며, 특정 할인 쿠폰을 선택하면 해당 쿠폰의 이름("가입 기념! $5 할인 쿠폰")이 노출된다', () => {
22-
cy.get('@shippingList')
23-
.eq(2)
24-
.findByRole('button', { name: '없음' })
25-
.click();
22+
cy.get('@shippingList').eq(2).findByText('없음').click();
2623
cy.findByText('가입 기념! $5 할인 쿠폰').click();
2724

2825
cy.get('@shippingList')
2926
.eq(2)
30-
.findByRole('button', { name: '가입 기념! $5 할인 쿠폰' })
27+
.findByText('가입 기념! $5 할인 쿠폰')
3128
.should('exist');
3229
});
3330

@@ -110,10 +107,7 @@ describe('결제 정보', () => {
110107
});
111108

112109
it('배송 정보에서 특정 할인 쿠폰을 선택하면 결제 정보에 해당 쿠폰 정보가 노출되며, 결제 금액이 재계산된다', () => {
113-
cy.get('@shippingList')
114-
.eq(2)
115-
.findByRole('button', { name: '없음' })
116-
.click();
110+
cy.get('@shippingList').eq(2).findByText('없음').click();
117111
cy.findByText('가입 기념! $5 할인 쿠폰').click();
118112

119113
cy.get('@paymentList').eq(0).findByText('$1,251.00').should('exist');

package.json

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,15 +53,15 @@
5353
"@storybook/react-vite": "^9.0.18",
5454
"@storybook/testing-library": "^0.2.2",
5555
"@tanstack/react-query-devtools": "^4.29.23",
56-
"@testing-library/cypress": "^9.0.0",
57-
"@testing-library/jest-dom": "^5.16.5",
58-
"@testing-library/react": "^14.0.0",
59-
"@testing-library/user-event": "^14.4.3",
60-
"@types/react": "^18.2.15",
61-
"@types/react-dom": "^18.2.7",
56+
"@testing-library/cypress": "^10.0.3",
57+
"@testing-library/jest-dom": "^6.6.4",
58+
"@testing-library/react": "^16.3.0",
59+
"@testing-library/user-event": "^14.6.1",
60+
"@types/react": "^19.1.9",
61+
"@types/react-dom": "^19.1.7",
6262
"@vitejs/plugin-react": "^4.7.0",
6363
"@vitest/ui": "^3.2.4",
64-
"chromatic": "^9.1.0",
64+
"chromatic": "^13.1.3",
6565
"concurrently": "8.2.0",
6666
"cypress": "^12.17.1",
6767
"cypress-real-events": "^1.11.0",
@@ -87,7 +87,7 @@
8787
"vitest": "^3.2.4"
8888
},
8989
"overrides": {
90-
"@testing-library/dom": "^9.0.1"
90+
"@testing-library/dom": "^10.0.4"
9191
},
9292
"msw": {
9393
"workerDirectory": "public"

pnpm-lock.yaml

Lines changed: 128 additions & 345 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

server/index.js

Lines changed: 65 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ import fs from 'fs';
66
import path from 'path';
77
import dotenv from 'dotenv';
88

9-
import productsJSON from './response/products.json' assert { type: 'json' };
10-
import categoriesJSON from './response/categories.json' assert { type: 'json' };
11-
import couponListJSON from './response/couponList.json' assert { type: 'json' };
12-
import usersJSON from './response/users.json' assert { type: 'json' };
9+
import productsJSON from './response/products.json' with { type: 'json' };
10+
import categoriesJSON from './response/categories.json' with { type: 'json' };
11+
import couponListJSON from './response/couponList.json' with { type: 'json' };
12+
import usersJSON from './response/users.json' with { type: 'json' };
1313

1414
dotenv.config();
1515

@@ -23,7 +23,7 @@ app.use(express.json());
2323
app.use(cors());
2424

2525
function wait(amount = 0) {
26-
return new Promise((resolve) => setTimeout(resolve, amount));
26+
return new Promise(resolve => setTimeout(resolve, amount));
2727
}
2828

2929
function getRandomArbitrary(min, max) {
@@ -40,42 +40,56 @@ function getProductsByCategoryId(products, categoryId) {
4040
const numberCategoryId = Number(categoryId);
4141

4242
return numberCategoryId > 0 && numberCategoryId < 6
43-
? products.filter((item) => item.category.id === numberCategoryId)
43+
? products.filter(item => item.category.id === numberCategoryId)
4444
: products;
4545
}
4646

4747
function getProductsByPrice(products, price) {
48-
return price ? products.filter((item) => item.price === Number(price)) : products;
48+
return price
49+
? products.filter(item => item.price === Number(price))
50+
: products;
4951
}
5052

5153
function getProductsByPriceRange({ products, minPrice, maxPrice }) {
5254
const minValue = minPrice ? Number(minPrice) : Number.MIN_SAFE_INTEGER;
5355
const maxValue = maxPrice ? Number(maxPrice) : Number.MAX_SAFE_INTEGER;
5456

55-
return products.filter((item) => item.price >= minValue && item.price <= maxValue);
57+
return products.filter(
58+
item => item.price >= minValue && item.price <= maxValue,
59+
);
5660
}
5761

5862
function getProductsByTitle(products, title) {
59-
return title ? products.filter((item) => item.title.includes(title)) : products;
63+
return title ? products.filter(item => item.title.includes(title)) : products;
6064
}
6165

6266
function getFilteredProductsByQuery(products, query) {
63-
const productsFilteredByCategoryId = getProductsByCategoryId(products, query.categoryId);
67+
const productsFilteredByCategoryId = getProductsByCategoryId(
68+
products,
69+
query.categoryId,
70+
);
6471
const productsFilteredByPriceRange = getProductsByPriceRange({
6572
products: productsFilteredByCategoryId,
6673
minPrice: query.minPrice,
6774
maxPrice: query.maxPrice,
6875
});
69-
const productsFilteredByPrice = getProductsByPrice(productsFilteredByPriceRange, query.price);
70-
const productsFilteredByTitle = getProductsByTitle(productsFilteredByPrice, query.title);
76+
const productsFilteredByPrice = getProductsByPrice(
77+
productsFilteredByPriceRange,
78+
query.price,
79+
);
80+
const productsFilteredByTitle = getProductsByTitle(
81+
productsFilteredByPrice,
82+
query.title,
83+
);
7184

7285
return productsFilteredByTitle;
7386
}
7487

7588
function getSliceIndex(products, query) {
7689
const offset = query.offset ? Number(query.offset) : 0;
7790
const limit = query.limit ? Number(query.limit) : products.length;
78-
const endIndex = offset + limit > products.length ? products.length : offset + limit;
91+
const endIndex =
92+
offset + limit > products.length ? products.length : offset + limit;
7993

8094
return {
8195
startIndex: offset,
@@ -89,7 +103,11 @@ const IV_LENGTH = 16; // For AES, this is always 16
89103

90104
function encrypt(text) {
91105
let iv = crypto.randomBytes(IV_LENGTH);
92-
let cipher = crypto.createCipheriv('aes-256-cbc', Buffer.from(SECURITY_KEY), iv);
106+
let cipher = crypto.createCipheriv(
107+
'aes-256-cbc',
108+
Buffer.from(SECURITY_KEY),
109+
iv,
110+
);
93111
let encrypted = cipher.update(text);
94112

95113
encrypted = Buffer.concat([encrypted, cipher.final()]);
@@ -101,7 +119,11 @@ function decrypt(text) {
101119
let textParts = text.split(':');
102120
let iv = Buffer.from(textParts.shift(), 'hex');
103121
let encryptedText = Buffer.from(textParts.join(':'), 'hex');
104-
let decipher = crypto.createDecipheriv('aes-256-cbc', Buffer.from(SECURITY_KEY), iv);
122+
let decipher = crypto.createDecipheriv(
123+
'aes-256-cbc',
124+
Buffer.from(SECURITY_KEY),
125+
iv,
126+
);
105127
let decrypted = decipher.update(encryptedText);
106128

107129
decrypted = Buffer.concat([decrypted, decipher.final()]);
@@ -126,10 +148,14 @@ app.get('/user', (req, res) => {
126148

127149
app.post('/login', (req, res) => {
128150
const { email, password } = req.body;
129-
const result = usersJSON.users.find((user) => user.email === email && user.password === password);
151+
const result = usersJSON.users.find(
152+
user => user.email === email && user.password === password,
153+
);
130154

131155
if (!result) {
132-
return res.status(401).send({ errorCode: 401000, message: '정보가 일치하지 않습니다.' });
156+
return res
157+
.status(401)
158+
.send({ errorCode: 401000, message: '정보가 일치하지 않습니다.' });
133159
}
134160

135161
const cookieConfig = {
@@ -148,27 +174,35 @@ app.post('/users', (req, res) => {
148174
const { users } = usersJSON;
149175

150176
if (!password.length) {
151-
return res
152-
.status(400)
153-
.send({ field: 'password', errorCode: 400001, message: '패스워드를 입력해주세요!' });
177+
return res.status(400).send({
178+
field: 'password',
179+
errorCode: 400001,
180+
message: '패스워드를 입력해주세요!',
181+
});
154182
}
155183

156184
if (!name.length) {
157-
return res
158-
.status(400)
159-
.send({ field: 'name', errorCode: 400002, message: '이메일을 입력해주세요!' });
185+
return res.status(400).send({
186+
field: 'name',
187+
errorCode: 400002,
188+
message: '이메일을 입력해주세요!',
189+
});
160190
}
161191

162192
if (!email.length || !EMAIL_PATTERN.test(email)) {
163-
return res
164-
.status(400)
165-
.send({ field: 'email', errorCode: 400003, message: '잘못된 이메일 양식입니다!' });
193+
return res.status(400).send({
194+
field: 'email',
195+
errorCode: 400003,
196+
message: '잘못된 이메일 양식입니다!',
197+
});
166198
}
167199

168-
if (users.find((user) => user.email === email)) {
169-
return res
170-
.status(400)
171-
.send({ field: 'email', errorCode: 400004, message: '이미 존재하는 메일입니다!' });
200+
if (users.find(user => user.email === email)) {
201+
return res.status(400).send({
202+
field: 'email',
203+
errorCode: 400004,
204+
message: '이미 존재하는 메일입니다!',
205+
});
172206
}
173207

174208
const newUser = { id: users.length + 1, name, email, password };
@@ -238,7 +272,7 @@ app.post('/log', (req, res) => {
238272
fs.appendFileSync(
239273
'./server/paymentResult.log',
240274
`LOG[${level}]: userId: ${userId} | date: ${new Date()} | message: ${message}\n`,
241-
(error) => {
275+
error => {
242276
throw error;
243277
},
244278
);

src/pages/cart/components/tests/PageTitle.spec.jsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,12 @@ it('pageTitle 스냅샷 테스트(toMatchInlineSnapshot)', async () => {
99
expect(container).toMatchInlineSnapshot(`
1010
<div>
1111
<h1
12-
class="MuiTypography-root MuiTypography-h4 css-1lnl64-MuiTypography-root"
12+
class="MuiTypography-root MuiTypography-h4 css-1ci4e74-MuiTypography-root"
1313
>
1414
상품 리스트
1515
</h1>
1616
<div
17+
id="_rht_toaster"
1718
style="position: fixed; z-index: 9999; top: 16px; left: 16px; right: 16px; bottom: 16px; pointer-events: none;"
1819
/>
1920
</div>

src/pages/cart/components/tests/__snapshots__/PageTitle.spec.jsx.snap

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@
33
exports[`pageTitle 스냅샷 테스트(toMatchSnapshot) 1`] = `
44
<div>
55
<h1
6-
class="MuiTypography-root MuiTypography-h4 css-1lnl64-MuiTypography-root"
6+
class="MuiTypography-root MuiTypography-h4 css-1ci4e74-MuiTypography-root"
77
>
88
상품 리스트
99
</h1>
1010
<div
11+
id="_rht_toaster"
1112
style="position: fixed; z-index: 9999; top: 16px; left: 16px; right: 16px; bottom: 16px; pointer-events: none;"
1213
/>
1314
</div>

src/pages/home/components/SkeletonProductCard.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {
1010
import React from 'react';
1111

1212
const SkeletonProductCard = () => (
13-
<Grid size={{ xs: 6, sm: 6, md: 3 }}>
13+
<Grid size={{ xs: 6, sm: 6, md: 3 }} data-testid="product-skeleton">
1414
<Card sx={{ maxWidth: 345 }}>
1515
<Skeleton variant="rectangular" height="100" />
1616
<CardContent>

src/pages/home/components/tests/ProductFilter.spec.jsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { screen } from '@testing-library/react';
2-
import { vi } from 'node_modules/vitest/dist/index';
32
import React from 'react';
43

54
import ProductFilter from '@/pages/home/components/ProductFilter';

src/pages/purchase/components/CouponListTableRow.jsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,12 @@ const CouponListTableRow = () => {
2626
<TableCell>
2727
<FormControl fullWidth size="small">
2828
<InputLabel>쿠폰 리스트</InputLabel>
29-
<Select value={selectedValue} label="쿠폰 리스트" onChange={onChange}>
29+
<Select
30+
value={selectedValue}
31+
label="쿠폰 리스트"
32+
aria-label="쿠폰 리스트"
33+
onChange={onChange}
34+
>
3035
<MenuItem value={NO_COUPON_ID}>없음</MenuItem>
3136
{couponList.map(({ name, id }) => (
3237
<MenuItem value={id} key={id}>

0 commit comments

Comments
 (0)