Skip to content
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

[Feature/FE] 웹 접근성을 개선. #788

Merged
merged 11 commits into from
Oct 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 16 additions & 13 deletions frontend/cypress/e2e/spec.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@ describe('비회원 사용자 기본 플로우', () => {
cy.wait('@productsRequest');

cy.findByRole('region', { name: /제품/ })
.findAllByRole('article')
.findAllByRole('link')
.should('be.visible');
});

it('홈 페이지에 접속하면 후기를 조회할 수 있다.', () => {
cy.wait('@reviewsRequest');

cy.findByRole('region', { name: /후기/ })
.findAllByRole('article')
.findAllByRole('link')
.should('be.visible');
});

Expand All @@ -33,9 +33,11 @@ describe('비회원 사용자 기본 플로우', () => {
cy.findByRole('region', { name: /후기/ }).isCardImageLoadDone();
});

cy.findByRole('region', {
name: '무한스크롤 목록 끝 지표',
}).scrollIntoView();
cy.findByRole('region', { name: /후기/ })
.findAllByRole('link')
.should('be.visible')
.last()
.scrollIntoView();

cy.wait('@reviewsRequest').then((res) => {
const page = new URL(res.request.url).searchParams.get('page');
Expand All @@ -52,7 +54,7 @@ describe('비회원 사용자 기본 플로우', () => {
cy.wait('@productsRequest');

cy.findByRole('region', { name: /키보드/ })
.findAllByRole('article')
.findAllByRole('link')
.should('be.visible');
});

Expand All @@ -63,7 +65,7 @@ describe('비회원 사용자 기본 플로우', () => {
cy.wait('@productsRequest');

cy.findByRole('region', { name: /마우스/ })
.findAllByRole('article')
.findAllByRole('link')
.should('be.visible');
});

Expand All @@ -74,7 +76,7 @@ describe('비회원 사용자 기본 플로우', () => {
cy.wait('@productsRequest');

cy.findByRole('region', { name: /모니터/ })
.findAllByRole('article')
.findAllByRole('link')
.should('be.visible');
});

Expand All @@ -85,7 +87,7 @@ describe('비회원 사용자 기본 플로우', () => {
cy.wait('@productsRequest');

cy.findByRole('region', { name: /거치대/ })
.findAllByRole('article')
.findAllByRole('link')
.should('be.visible');
});

Expand All @@ -95,26 +97,27 @@ describe('비회원 사용자 기본 플로우', () => {

cy.wait('@productsRequest');
cy.findByRole('region', { name: /소프트웨어/ })
.findAllByRole('article')
.findAllByRole('link')
.should('be.visible');
});

it('제품 상세 페이지에 진입하면, 제품 사진과 리뷰와 통계정보를 볼 수 있다.', () => {
cy.wait('@productsRequest');

cy.findByRole('region', { name: '인기 있는 제품' })
.findAllByRole('article')
.findAllByRole('link')
.first()
// .findByRole('img')
.click({ force: true });

// 후기는 없는 제품이 있을 수도 있기 때문에 삭제하거나 빈 데이터 이미지 표시 필요
// cy.findByRole('region', { name: '최근 후기' })
// .findAllByRole('article')
// .findAllByRole('link')
// .should('be.visible');
cy.wait('@productRequest');

expect(cy.findByRole('img', { name: '제품 이미지' })).to.exist;
expect(cy.findByRole('region', { name: '제품 상세 정보' }).findByRole('img')).to
.exist;

cy.findByRole('region', { name: '통계 정보' })
.scrollIntoView()
Expand Down
6 changes: 2 additions & 4 deletions frontend/cypress/support/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Cypress.Commands.add(
{ prevSubject: true },
(card: Cypress.Chainable<JQuery<HTMLElement>>) => {
cy.wrap(card)
.findAllByRole('article')
.findAllByRole('link')
.each((element) => {
cy.wrap(element).get('img').should('be.visible');
});
Expand All @@ -16,8 +16,6 @@ Cypress.Commands.add(
'isNotLoading',
{ prevSubject: true },
(container: Cypress.Chainable<JQuery<HTMLElement>>) => {
cy.wrap(container)
.findByRole('region', { name: 'loading' })
.should('not.exist');
cy.wrap(container).findByRole('region', { name: 'loading' }).should('not.exist');
}
);
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import styled, { css } from 'styled-components';

export const Container = styled.article<{ index: number; size: 's' | 'm' | 'l' }>`
export const Container = styled.div<{ index: number; size: 's' | 'm' | 'l' }>`
display: flex;
flex-direction: column;
justify-content: space-between;
Expand All @@ -16,9 +16,6 @@ export const Container = styled.article<{ index: number; size: 's' | 'm' | 'l' }
transform: scale(1.03);
transition: 0.2s;
}
h2 {
text-decoration: underline;
}
}

${({ index }) => css`
Expand All @@ -41,6 +38,7 @@ export const Container = styled.article<{ index: number; size: 's' | 'm' | 'l' }
`;
export const ImageWrapper = styled.div`
width: 100%;
aspect-ratio: 1 / 1;
overflow: hidden;
border: 1px solid ${({ theme }) => theme.colors.secondary};
background-color: #fff;
Expand All @@ -64,7 +62,12 @@ const nameFontSize = {
l: '1rem',
};

export const Name = styled.h2<{ size: 's' | 'm' | 'l' }>`
export const Name = styled.p<{ size: 's' | 'm' | 'l' }>`
line-height: 1.3;
font-weight: 500;
font-size: ${({ size }) => nameFontSize[size]};

${Container}:hover & {
text-decoration: underline;
}
`;
4 changes: 2 additions & 2 deletions frontend/src/components/Product/ProductCard/ProductCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ function ProductCard({
size = 'l',
}: Props) {
return (
<S.Container aria-label={name} index={index} size={size}>
<S.Container index={index} size={size}>
<S.ImageWrapper>
<LazyImage src={imageUrl} />
<LazyImage src={imageUrl} alt={''} />
</S.ImageWrapper>
<S.Name size={size}>{name}</S.Name>
<S.BottomWrapper>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import styled from 'styled-components';

export const Container = styled.div`
export const Container = styled.section`
display: flex;
flex-direction: column;
padding: 1rem;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ function ProductDetail({ product }: Props) {
const { imageUrl, name, rating, reviewCount } = product;

return (
<S.Container>
<S.Image src={imageUrl} aria-label="제품 이미지" />
<S.Container aria-label="제품 상세 정보">
<S.Image src={imageUrl} alt={''} />
<S.Wrapper>
<S.Name>{name}</S.Name>
<S.Details>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export const FlexWrapper = styled.div`
}
@media screen and ${device.desktop} {
min-height: 28rem;
justify-content: space-between;
-ms-overflow-style: none;
scrollbar-width: none;
&::-webkit-scrollbar {
Expand All @@ -36,12 +37,24 @@ export const FlexWrapper = styled.div`
`}
`;

export const Grid = styled.ul<{ columnCount: number }>`
display: grid;
grid-template-columns: repeat(${({ columnCount }) => columnCount}, 1fr);
`;

export const Title = styled.h1`
font-size: 1.5rem;
`;

export const CustomLink = styled(Link)``;

export const ProductLink = styled(Link)`
display: flex;
justify-content: center;
width: max-content;
margin: 0 auto;
`;

export const Wrapper = styled.div`
margin: 1rem auto 0 auto;
width: 100%;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
import { Link } from 'react-router-dom';

import InfiniteScroll from '@/components/common/InfiniteScroll/InfiniteScroll';
import Masonry from '@/components/common/Masonry/Masonry';
import NoDataPlaceholder from '@/components/common/NoDataPlaceholder/NoDataPlaceholder';

import ProductCard from '@/components/Product/ProductCard/ProductCard';
Expand Down Expand Up @@ -42,16 +39,18 @@ function ProductListSection({
displayType === 'flex' ? DEVICE_TO_SIZE[device] : device === 'tablet' ? 'm' : 'l';

const productList = data.map(({ id, imageUrl, name, rating, reviewCount }, index) => (
<Link to={`${ROUTES.PRODUCT}/${id}`} key={id}>
<ProductCard
imageUrl={imageUrl}
name={name}
rating={rating}
reviewCount={reviewCount}
index={index % pageSize}
size={cardSize}
/>
</Link>
<li key={id}>
<S.ProductLink to={`${ROUTES.PRODUCT}/${id}`}>
<ProductCard
imageUrl={imageUrl}
name={name}
rating={rating}
reviewCount={reviewCount}
index={index % pageSize}
size={cardSize}
/>
</S.ProductLink>
</li>
));

return (
Expand All @@ -69,11 +68,11 @@ function ProductListSection({
isLoading={isLoading}
isError={isError}
>
<Masonry
<S.Grid
columnCount={displayType === 'masonry' ? ROW_COUNT(displayWidth) : pageSize}
>
{productList}
</Masonry>
</S.Grid>
</InfiniteScroll>
)}
</S.Wrapper>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ type Props = Partial<Pick<Review, 'id' | 'rating' | 'content'>> & {
handleEdit?: (reviewInput: ReviewInput, id: number) => Promise<void>;
isEdit: boolean;
handleUnmount?: () => void;
handleFocus?: () => void;
animationTrigger?: boolean;
};

Expand All @@ -21,6 +22,7 @@ function ReviewBottomSheet({
rating,
content,
handleUnmount,
handleFocus,
animationTrigger,
}: Props) {
const handleCloseWithSubmit = async (reviewInput: ReviewInput) => {
Expand All @@ -31,23 +33,25 @@ function ReviewBottomSheet({
await handleSubmit(reviewInput);
}
handleClose();
handleFocus();
} catch (error) {
console.log(error);
}
};

return (
<BottomSheet
handleClose={handleClose}
handleUnmount={handleUnmount}
animationTrigger={animationTrigger}
>
<S.Button onClick={handleClose}>닫기</S.Button>
<ReviewForm
handleSubmit={handleCloseWithSubmit}
isEdit={isEdit ? true : false}
rating={rating}
content={content}
/>
<S.Button onClick={handleClose}>닫기</S.Button>
</BottomSheet>
);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Link } from 'react-router-dom';
import styled, { css } from 'styled-components';

export const Container = styled.article<{ index: number }>`
export const Container = styled.div<{ index: number }>`
display: flex;
gap: 1rem;
border-radius: 0.375rem;
Expand Down
3 changes: 3 additions & 0 deletions frontend/src/components/Review/ReviewCard/ReviewCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ type Props = {
reviewData: Omit<Review, 'id'>;
handleDelete?: (id: number) => void;
handleEdit?: (reviewInput: ReviewInput, id: number) => Promise<void>;
handleFocus?: () => void;
index?: number;
userNameVisible?: boolean;
};
Expand All @@ -25,6 +26,7 @@ function ReviewCard({
reviewId,
handleDelete,
handleEdit,
handleFocus,
reviewData,
index = 0,
userNameVisible = true,
Expand Down Expand Up @@ -52,6 +54,7 @@ function ReviewCard({

const handleDeleteClick = () => {
handleDelete(reviewId);
handleFocus();
};

return (
Expand Down
Loading