Skip to content

Commit

Permalink
feat: add articles, article details page e2e cypress tests
Browse files Browse the repository at this point in the history
  • Loading branch information
TomatoVan committed Apr 1, 2024
1 parent 8873745 commit ce8c139
Show file tree
Hide file tree
Showing 13 changed files with 176 additions and 14 deletions.
33 changes: 30 additions & 3 deletions cypress/e2e/articles/article-details.cy.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,32 @@
describe('empty spec', () => {
it('passes', () => {
cy.visit('https://example.cypress.io');
let currentArticleId = '';
describe('to article details page', () => {
beforeEach(() => {
cy.login();
cy.createArticle().then((article) => {
currentArticleId = article.id;
cy.visit(`articles/${article.id}`);
});
});
// Add new article - test everything - delete article
afterEach(() => {
cy.removeArticle(currentArticleId);
});
it('article details page loaded', () => {
cy.getByTestId('ArticlesDetails.Info').should('exist');
});
it('article details recommendations list loaded', () => {
cy.getByTestId('ArticleRecommendationsList').should('exist');
});
it('article details comments list', () => {
cy.getByTestId('ArticlesDetails.Info');
cy.getByTestId('AddCommentForm').scrollIntoView();
cy.addComment('text');
cy.getByTestId('CommentCard.Content').should('have.length', 1);
});
it('article details rating', () => {
cy.getByTestId('ArticlesDetails.Info');
cy.getByTestId('RatingCard').scrollIntoView();
cy.setRate(3, 'feedback test');
cy.get('[data-selected=true]').should('have.length', 3);
});
});
6 changes: 6 additions & 0 deletions cypress/support/commands.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import * as commonCommands from './commands/common';
import * as profileCommands from './commands/profile';
import * as articleCommands from './commands/article';
import * as commentsCommands from './commands/comments';
import * as ratingCommands from './commands/rating';

Cypress.Commands.addAll(commonCommands);
Cypress.Commands.addAll(profileCommands);
Cypress.Commands.addAll(articleCommands);
Cypress.Commands.addAll(commentsCommands);
Cypress.Commands.addAll(ratingCommands);

export {};
37 changes: 37 additions & 0 deletions cypress/support/commands/article.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { Article } from '../../../src/entities/Article';

const defaultArticle = {
title: 'TESTING ARTICLE',
subtitle: 'Subtitle text',
img: 'https://avatars.mds.yandex.net/get-zen_doc/2746556/pub_5f50dd'
+ '7e1a1ddf4776aa5569_5f50decd2506f211d1de6284/scale_1200',
views: 1022,
createdAt: '26.02.2022',
userId: '1',
type: [
'SCIENCE',
],
blocks: [],
};

export const createArticle = (article?: Article) => cy.request({
method: 'POST',
url: 'http://localhost:8000/articles',
headers: { Authorization: 'asasf' },
body: article ?? defaultArticle,
}).then((resp) => resp.body);

export const removeArticle = (articleId: string) => cy.request({
method: 'DELETE',
url: `http://localhost:8000/articles/${articleId}`,
headers: { Authorization: 'asasf' },
});

declare global {
namespace Cypress {
interface Chainable {
createArticle(article?: Article): Chainable<Article>;
removeArticle(articleId: string): Chainable<void>;
}
}
}
12 changes: 12 additions & 0 deletions cypress/support/commands/comments.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export const addComment = (text: string) => {
cy.getByTestId('AddCommentForm.Input').type(text);
cy.getByTestId('AddCommentForm.Button').click();
};

declare global {
namespace Cypress {
interface Chainable {
addComment(text: string): Chainable<void>;
}
}
}
13 changes: 13 additions & 0 deletions cypress/support/commands/rating.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export const setRate = (starsCount = 5, feedback = 'feedback') => {
cy.getByTestId(`StarRating.${starsCount}`).click();
cy.getByTestId('RatingCard.Input').type(feedback);
cy.getByTestId('RatingCard.Send').click();
};

declare global {
namespace Cypress {
interface Chainable {
setRate(starsCount: number, feedback: string): Chainable<void>;
}
}
}
26 changes: 26 additions & 0 deletions json-server/db.json
Original file line number Diff line number Diff line change
Expand Up @@ -563,6 +563,32 @@
],
"blocks": [],
"id": "6f91vPH"
},
{
"title": "TESTING ARTICLE",
"subtitle": "Subtitle text",
"img": "https://avatars.mds.yandex.net/get-zen_doc/2746556/pub_5f50dd7e1a1ddf4776aa5569_5f50decd2506f211d1de6284/scale_1200",
"views": 1022,
"createdAt": "26.02.2022",
"userId": "1",
"type": [
"SCIENCE"
],
"blocks": [],
"id": "y1D5B71"
},
{
"title": "TESTING ARTICLE",
"subtitle": "Subtitle text",
"img": "https://avatars.mds.yandex.net/get-zen_doc/2746556/pub_5f50dd7e1a1ddf4776aa5569_5f50decd2506f211d1de6284/scale_1200",
"views": 1022,
"createdAt": "26.02.2022",
"userId": "1",
"type": [
"SCIENCE"
],
"blocks": [],
"id": "3u59urr"
}
],
"comments": [
Expand Down
2 changes: 1 addition & 1 deletion src/entities/Article/ui/ArticleDetails/ArticleDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ export const ArticleDetails = memo(({ className, id }: ArticleDetailsProps) => {
className={cls.avatar}
/>
</HStack>
<VStack gap="4" max>
<VStack gap="4" max data-testid="ArticlesDetails.Info">
<Text
className={cls.title}
size={TextSize.L}
Expand Down
16 changes: 13 additions & 3 deletions src/entities/Comment/ui/CommentCard/CommentCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,19 @@ export const CommentCard = memo(({ className, comment, isLoading }: CommentCardP

if (isLoading) {
return (
<div className={classNames(cls.CommentCard, {}, [className, cls.loading])}>
<VStack
data-testid="CommentCard.Loading"
gap="8"
max
className={classNames(cls.CommentCard, {}, [className, cls.loading])}
>
<div className={cls.header}>
<Skeleton width={30} height={30} border="50%" />
<Skeleton width={100} height={16} className={cls.username} />
</div>
<Skeleton height={50} width="100%" className={cls.text} />

</div>
</VStack>
);
}

Expand All @@ -37,7 +42,12 @@ export const CommentCard = memo(({ className, comment, isLoading }: CommentCardP
}

return (
<VStack max gap="8" className={classNames(cls.CommentCard, {}, [className])}>
<VStack
data-testid="CommentCard.Content"
max
gap="8"
className={classNames(cls.CommentCard, {}, [className])}
>
<AppLink to={getRouteProfile(comment.user.id)} className={cls.header}>
{comment.user.avatar && <Avatar src={comment.user.avatar} alt={comment.user.username} size={30} />}
<Text className={cls.username} title={comment.user.username} />
Expand Down
18 changes: 15 additions & 3 deletions src/entities/Rating/ui/RatingCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ export const RatingCard = memo((props: RatingCardProps) => {
title={feedbackTitle}
/>
<Input
data-testid="RatingCard.Input"
value={feedback}
onChange={setFeedback}
placeholder={t('Ваш отзыв')}
Expand All @@ -69,7 +70,11 @@ export const RatingCard = memo((props: RatingCardProps) => {
);

return (
<Card max className={classNames('', {}, [className])}>
<Card
data-testid="RatingCard"
max
className={classNames('', {}, [className])}
>
<VStack align="center" gap="8" max>
<Text title={starsCount ? t('Thanks for review!') : title} />
<StarRating selectedStars={starsCount} size={40} onSelect={onSelectStars} />
Expand All @@ -79,10 +84,17 @@ export const RatingCard = memo((props: RatingCardProps) => {
<VStack max gap="32">
{modalContent}
<HStack max gap="16" justify="between">
<Button onClick={cancelHandle} theme={ButtonTheme.OUTLINE_RED}>
<Button
data-testid="RatingCard.Close"
onClick={cancelHandle}
theme={ButtonTheme.OUTLINE_RED}
>
{t('Закрыть')}
</Button>
<Button onClick={acceptHandle}>
<Button
data-testid="RatingCard.Send"
onClick={acceptHandle}
>
{t('Отправить')}
</Button>
</HStack>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,21 @@ const AddCommentForm = memo((props: AddCommentFormProps) => {

return (
<DynamicModuleLoader reducers={reducers}>
<HStack justify="between" max className={classNames(cls.AddCommentForm, {}, [className])}>
<HStack
data-testid="AddCommentForm"
justify="between"
max
className={classNames(cls.AddCommentForm, {}, [className])}
>
<Input
data-testid="AddCommentForm.Input"
value={text}
placeholder={t('Enter comment text')}
className={cls.input}
onChange={onCommentTextChange}
/>
<Button
data-testid="AddCommentForm.Button"
theme={ButtonTheme.OUTLINE}
onClick={onSendHandler}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,12 @@ export const ArticleRecommendationsList = memo((props: ArticleRecommendationsLis
}

return (
<VStack gap="16" max className={classNames('', {}, [className])}>
<VStack
data-testid="ArticleRecommendationsList"
gap="16"
max
className={classNames('', {}, [className])}
>
<Text
size={TextSize.L}
title={t('Recommend')}
Expand Down
3 changes: 2 additions & 1 deletion src/shared/ui/Stack/Flex/Flex.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export const Flex = (props: FlexProps) => {
direction = 'row',
gap,
max,
...otherProps
} = props;

const classes = [
Expand All @@ -68,7 +69,7 @@ export const Flex = (props: FlexProps) => {
};

return (
<div className={classNames(cls.Flex, mods, classes)}>
<div className={classNames(cls.Flex, mods, classes)} {...otherProps}>
{children}
</div>
);
Expand Down
8 changes: 7 additions & 1 deletion src/shared/ui/StarRating/StarRating.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,20 @@ export const StarRating = memo((props: StarRatingProps) => {
<div className={classNames(cls.StarRating, {}, [className])}>
{stars.map((starNumber) => (
<Icon
className={classNames(cls.StarIcon, { [cls.selected]: isSelected }, [currentStarsCount >= starNumber ? cls.hovered : cls.normal])}
className={classNames(
cls.StarIcon,
{ [cls.selected]: isSelected },
[currentStarsCount >= starNumber ? cls.hovered : cls.normal],
)}
Svg={StarIcon}
key={starNumber}
width={size}
height={size}
onMouseLeave={onLeave}
onMouseEnter={() => onHover(starNumber)}
onClick={() => onClick(starNumber)}
data-testid={`StarRating.${starNumber}`}
data-selected={currentStarsCount >= starNumber}

/>
))}
Expand Down

0 comments on commit ce8c139

Please sign in to comment.