mirror of
https://github.com/Raghu-Ch/angular-challenges.git
synced 2026-02-10 12:53:03 -05:00
Merge branch 'main' of https://github.com/kabrunko-dev/angular-challenges
This commit is contained in:
@@ -231,6 +231,15 @@
|
|||||||
"contributions": [
|
"contributions": [
|
||||||
"translation-ru"
|
"translation-ru"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "Dinozavvvr",
|
||||||
|
"name": "Dinar Shagaliev",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/45518871?v=4",
|
||||||
|
"profile": "https://github.com/Dinozavvvr",
|
||||||
|
"contributions": [
|
||||||
|
"translation-ru"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"contributorsPerLine": 7,
|
"contributorsPerLine": 7,
|
||||||
|
|||||||
@@ -57,7 +57,8 @@ Check [all 47 challenges](https://angular-challenges.vercel.app/)
|
|||||||
<td align="center" valign="top" width="14.28%"><a href="http://www.streamoverlaypro.com"><img src="https://avatars.githubusercontent.com/u/1978642?v=4?s=100" width="100px;" alt="Erick Rodriguez"/><br /><sub><b>Erick Rodriguez</b></sub></a><br /><a href="#translation-es-ErickRodrCodes" title="Translate in Spanish">🇪🇸</a></td>
|
<td align="center" valign="top" width="14.28%"><a href="http://www.streamoverlaypro.com"><img src="https://avatars.githubusercontent.com/u/1978642?v=4?s=100" width="100px;" alt="Erick Rodriguez"/><br /><sub><b>Erick Rodriguez</b></sub></a><br /><a href="#translation-es-ErickRodrCodes" title="Translate in Spanish">🇪🇸</a></td>
|
||||||
<td align="center" valign="top" width="14.28%"><a href="https://eduardoroth.dev"><img src="https://avatars.githubusercontent.com/u/5419161?v=4?s=100" width="100px;" alt="Eduardo Roth"/><br /><sub><b>Eduardo Roth</b></sub></a><br /><a href="https://github.com/tomalaforge/angular-challenges/commits?author=eduardoRoth" title="Documentation">📖</a> <a href="#translation-es-eduardoRoth" title="Translate in Spanish">🇪🇸</a></td>
|
<td align="center" valign="top" width="14.28%"><a href="https://eduardoroth.dev"><img src="https://avatars.githubusercontent.com/u/5419161?v=4?s=100" width="100px;" alt="Eduardo Roth"/><br /><sub><b>Eduardo Roth</b></sub></a><br /><a href="https://github.com/tomalaforge/angular-challenges/commits?author=eduardoRoth" title="Documentation">📖</a> <a href="#translation-es-eduardoRoth" title="Translate in Spanish">🇪🇸</a></td>
|
||||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/1fbr"><img src="https://avatars.githubusercontent.com/u/63980689?v=4?s=100" width="100px;" alt="Fernando Bello"/><br /><sub><b>Fernando Bello</b></sub></a><br /><a href="https://github.com/tomalaforge/angular-challenges/commits?author=1fbr" title="Documentation">📖</a></td>
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/1fbr"><img src="https://avatars.githubusercontent.com/u/63980689?v=4?s=100" width="100px;" alt="Fernando Bello"/><br /><sub><b>Fernando Bello</b></sub></a><br /><a href="https://github.com/tomalaforge/angular-challenges/commits?author=1fbr" title="Documentation">📖</a></td>
|
||||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/webbomj"><img src="https://avatars.githubusercontent.com/u/86595717?v=4?s=100" width="100px;" alt="Лапин Андрей (Lapin Andrey)"/><br /><sub><b>Лапин Андрей (Lapin Andrey)</b></sub></a><br /><a href="#translation-ru" title="Translate in Russian">🇷🇺</a></td>
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/webbomj"><img src="https://avatars.githubusercontent.com/u/86595717?v=4?s=100" width="100px;" alt="Лапин Андрей (Lapin Andrey)"/><br /><sub><b>Лапин Андрей (Lapin Andrey)</b></sub></a><br /><a href="#translation-ru-webbomj" title="Translate in Russian">🇷🇺</a></td>
|
||||||
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Dinozavvvr"><img src="https://avatars.githubusercontent.com/u/45518871?v=4?s=100" width="100px;" alt="Dinar Shagaliev"/><br /><sub><b>Dinar Shagaliev</b></sub></a><br /><a href="#translation-ru-Dinozavvvr" title="Translate in Russian">🇷🇺</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
<tfoot>
|
<tfoot>
|
||||||
|
|||||||
@@ -1,14 +1,17 @@
|
|||||||
---
|
---
|
||||||
import Default from '@astrojs/starlight/components/Hero.astro';
|
import Default from '@astrojs/starlight/components/Hero.astro';
|
||||||
import MyIcon from './MyIcon.astro';
|
import MyIcon from './MyIcon.astro';
|
||||||
|
import { getEntry } from 'astro:content';
|
||||||
|
|
||||||
const sponsorFetch = await fetch('https://ghs.vercel.app/v2/sponsors/tomalaforge');
|
const sponsorFetch = await fetch('https://ghs.vercel.app/v2/sponsors/tomalaforge');
|
||||||
const { sponsors } = await sponsorFetch.json();
|
const { sponsors } = await sponsorFetch.json();
|
||||||
|
|
||||||
|
const { lang } = Astro.props;
|
||||||
|
const { data } = await getEntry('i18n', lang);
|
||||||
---
|
---
|
||||||
|
|
||||||
<div class="sponsor-header button-hover">
|
<div class="sponsor-header button-hover">
|
||||||
<p>Big thanks to the people supporting this project:
|
<p>{data['sponsors.description']}
|
||||||
{sponsors.past.map(({username, avatar}) => (
|
{sponsors.past.map(({username, avatar}) => (
|
||||||
<a href=`https://github.com/${username}`>
|
<a href=`https://github.com/${username}`>
|
||||||
<img
|
<img
|
||||||
@@ -23,7 +26,7 @@ const { sponsors } = await sponsorFetch.json();
|
|||||||
))}
|
))}
|
||||||
</p>
|
</p>
|
||||||
<a class="action-button" href="https://github.com/sponsors/tomalaforge">
|
<a class="action-button" href="https://github.com/sponsors/tomalaforge">
|
||||||
<div>Join the list</div>
|
<div>{data['sponsors.joinButton']}</div>
|
||||||
<MyIcon name="heart" fill="none" stroke="currentColor" color="white" />
|
<MyIcon name="heart" fill="none" stroke="currentColor" color="white" />
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -60,6 +60,8 @@ const i18n = defineCollection({
|
|||||||
'subscription.note.description': z.string(),
|
'subscription.note.description': z.string(),
|
||||||
'contributor.title': z.string(),
|
'contributor.title': z.string(),
|
||||||
'contributor.subtitle': z.string(),
|
'contributor.subtitle': z.string(),
|
||||||
|
'sponsors.description': z.string(),
|
||||||
|
'sponsors.joinButton': z.string(),
|
||||||
})
|
})
|
||||||
.partial(),
|
.partial(),
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
---
|
||||||
|
title: 🟠 Оптимизация обнаружения изменений
|
||||||
|
description: Задание 12 посвящено оптимизации количества циклов обнаружения изменений при прокрутке
|
||||||
|
author: thomas-laforge
|
||||||
|
contributors:
|
||||||
|
- Dinozavvvr
|
||||||
|
challengeNumber: 12
|
||||||
|
command: performance-scroll-cd
|
||||||
|
sidebar:
|
||||||
|
order: 107
|
||||||
|
---
|
||||||
|
|
||||||
|
## Информация
|
||||||
|
|
||||||
|
В Angular есть библиотека под названием <b>Zone.js</b>, которая выполняет множество магии, чтобы упростить жизнь разработчика. Zone.js монкипатчит все события DOM, чтобы перепроверить и перерисовать представление, когда что-то изменилось внутри приложения. Разработчику не нужно вручную запускать обнаружение изменений.
|
||||||
|
|
||||||
|
Однако иногда Zone.js вызывает гораздо больше обнаружения изменений, чем это необходимо. Например, когда вы прослушиваете событие прокрутки, каждое событие прокрутки вызывает новый цикл обнаружения изменений.
|
||||||
|
|
||||||
|
В этом испытании нам нужно обновлять представление только в определенной позиции прокрутки, чтобы показать или скрыть кнопку. Все остальные циклы избыточны.
|
||||||
|
|
||||||
|
Чтобы лучше понять проблему, выполните профилирование вашего приложения с помощью Angular Dev Tools.
|
||||||
|
|
||||||
|
:::note
|
||||||
|
Если вы не знаете, как это сделать, сначала прочтите [введение в производительность](/challenges/performance/).
|
||||||
|
:::
|
||||||
|
|
||||||
|
Вы можете узнать больше деталей о загрязнении зон и способах его решения [здесь](https://angular.io/guide/change-detection-zone-pollution).
|
||||||
|
|
||||||
|
В следующем видео более подробно объясняется проблема этого приложения.
|
||||||
|
|
||||||
|
<video controls src="https://user-images.githubusercontent.com/30832608/209819211-58d9ddcf-e1ad-4a78-8a7a-2be9d729e3f1.mov">
|
||||||
|
</video>
|
||||||
|
|
||||||
|
## Утверждение
|
||||||
|
|
||||||
|
Ваша цель в этом испытании - избежать всех избыточных циклов обнаружения изменений и запускать обнаружение изменений только при необходимости.
|
||||||
|
|
||||||
|
## Ограничение:
|
||||||
|
|
||||||
|
Вы не можете глобально отключить Zone.js. Если этот код является частью большого проекта и вы отключите Zone.js, вы без сомнения сломаете ваше приложение.
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
---
|
||||||
|
title: 🟠 Оптимизация больших списков
|
||||||
|
description: Задание 37 посвящено изучению того, как виртуализация оптимизирует рендеринг больших списков
|
||||||
|
author: thomas-laforge
|
||||||
|
contributors:
|
||||||
|
- Dinozavvvr
|
||||||
|
challengeNumber: 37
|
||||||
|
command: performance-ngfor-biglist
|
||||||
|
sidebar:
|
||||||
|
order: 117
|
||||||
|
---
|
||||||
|
|
||||||
|
## Информация
|
||||||
|
|
||||||
|
В этом приложении мы будем отображать список из 100 000 человек, нажав на кнопку **loadList**. Если вы откроете панель разработчика Chrome, нажав **F12**, перейдите на вкладку <b>Source</b> и разверните элемент, чтобы увидеть список, вы заметите, что все 100 000 элементов отображаются в DOM, хотя мы можем видеть только около 20 элементов в видимой области. Этот процесс занимает много времени, поэтому приложение очень медленно отображает список.
|
||||||
|
|
||||||
|
Мы можем использовать <b>Angular DevTool</b>, чтобы профилировать наше приложение и понять, что происходит внутри нашего приложения. Я покажу вам, как это сделать в следующем видео.
|
||||||
|
|
||||||
|
<video controls src="https://github.com/tomalaforge/angular-challenges/assets/30832608/713403fa-2eda-49d5-a7c9-acdef8aacd34">
|
||||||
|
</video>
|
||||||
|
|
||||||
|
:::note
|
||||||
|
Если вы не знаете, как это сделать, сначала прочтите [введение в производительность](/challenges/performance/) и вернитесь после этого.
|
||||||
|
:::
|
||||||
|
|
||||||
|
## Утверждение
|
||||||
|
|
||||||
|
Цель этого испытания - реализовать лучшую альтернативу для отображения больших списков элементов.
|
||||||
|
|
||||||
|
## Подсказки:
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>Подсказка 1</summary>
|
||||||
|
|
||||||
|
Если вы не уверены, с чего начать, я рекомендую прочитать [документацию Angular CDK о виртуализации](https://material.angular.io/cdk/scrolling/overview).
|
||||||
|
|
||||||
|
</details>
|
||||||
51
docs/src/content/docs/ru/challenges/performance/index.mdx
Normal file
51
docs/src/content/docs/ru/challenges/performance/index.mdx
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
---
|
||||||
|
title: Производительность Angular-а
|
||||||
|
prev: false
|
||||||
|
next: false
|
||||||
|
contributors:
|
||||||
|
- Dinozavvvr
|
||||||
|
description: Узнайте, как использовать расширение Angular DevTools для Chrome.
|
||||||
|
noCommentSection: true
|
||||||
|
sidebar:
|
||||||
|
order: 1
|
||||||
|
---
|
||||||
|
|
||||||
|
import { LinkCard } from '@astrojs/starlight/components';
|
||||||
|
|
||||||
|
В этой серии испытаний по производительности вы узнаете, как оптимизировать и улучшить производительность вашего приложения Angular.
|
||||||
|
|
||||||
|
Прежде чем приступить к решению какого-либо испытания, я приглашаю вас скачать [расширение Angular DevTools для Chrome](https://chrome.google.com/webstore/detail/angular-devtools/ienfalfjdbdpebioblfackkekamfmbnh), если вы еще этого не сделали.
|
||||||
|
|
||||||
|
Это расширение позволяет профилировать ваше приложение и обнаруживать проблемы производительности, что очень полезно для понимания мест, где могут возникать проблемы с производительностью.
|
||||||
|
|
||||||
|
## Как его использовать
|
||||||
|
|
||||||
|
При запуске приложения Angular вы можете проверить страницу, нажав <b>F12</b>, что откроет <b>Инструменты разработчика Chrome</b>. Затем перейдите на вкладку <b>Angular</b>. Оттуда вы можете выбрать вкладку <b>Profiler</b>, как показано ниже.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Теперь вы можете профилировать свое приложение, нажав кнопку записи. Вы можете играть с вашим приложением и видеть, когда срабатывает обнаружение изменений и какие компоненты перерисовываются.
|
||||||
|
|
||||||
|
:::tip[Узнайте больше]
|
||||||
|
Вы можете узнать больше на [странице документации](https://angular.io/guide/devtools).
|
||||||
|
:::
|
||||||
|
|
||||||
|
Теперь, когда вы знаете, как использовать <b>Angular DevTool</b>, вы можете выбрать испытание и решить его с использованием профилирования.
|
||||||
|
|
||||||
|
<LinkCard
|
||||||
|
title="🟢 Default vs OnPush"
|
||||||
|
description="Узнайте разницу между стратегиями обнаружения изменений по умолчанию и OnPush."
|
||||||
|
href="/challenges/performance/34-default-onpush/"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<LinkCard
|
||||||
|
title="🟢 Мемоизация"
|
||||||
|
description="Узнайте силу чистых каналов."
|
||||||
|
href="/challenges/performance/35-memoize/"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<LinkCard
|
||||||
|
title="🟠 Оптимизация обнаружения изменений"
|
||||||
|
description="Узнайте, как убрать загрязнение зон."
|
||||||
|
href="/challenges/performance/12-scroll-cd/"
|
||||||
|
/>
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
---
|
||||||
|
title: 🟠 Ошибка в операторе высшего порядка RxJS
|
||||||
|
description: Задача 11 посвящена устранению ошибки в RxJS из-за операторов высшего порядка
|
||||||
|
author: thomas-laforge
|
||||||
|
contributors:
|
||||||
|
- Dinozavvvr
|
||||||
|
challengeNumber: 11
|
||||||
|
command: rxjs-pipe-bug
|
||||||
|
sidebar:
|
||||||
|
order: 114
|
||||||
|
---
|
||||||
|
|
||||||
|
Давайте погрузимся в удивительный мир RxJs.
|
||||||
|
|
||||||
|
Этот вызов вдохновлен реальным примером.
|
||||||
|
|
||||||
|
## Информация
|
||||||
|
|
||||||
|
### История пользователя
|
||||||
|
|
||||||
|
Нам нужна кнопка для каждой `Статья`. Когда мы нажимаем на нее, мы удаляем все объекты с этой `Статьей` в нашей базе данных _(Фейковая БД в нашем случае)_. Наконец, мы отображаем **Все [статьи] были удалены** в случае успешного удаления или **Ошибка: удаление некоторых [статей] не удалось** если удаление некоторых объектов не удалось.
|
||||||
|
|
||||||
|
### Ограничения:
|
||||||
|
|
||||||
|
Мы можем передавать в нашу БД для удаления только один объект за раз. БД ответит true, если данные были успешно удалены, и false в противном случае.
|
||||||
|
|
||||||
|
### Утверждение
|
||||||
|
|
||||||
|
Команда тестировщиков сообщает об **ошибке**. Интерфейс пользователя всегда показывает **Все [темы] были удалены**, даже если некоторые удаления не удалось.
|
||||||
|
|
||||||
|
👉 Найдите ошибку и исправьте ее.
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
---
|
||||||
|
title: 🟢 catchError
|
||||||
|
description: Задача 38 посвященя изучению завершения Observable.
|
||||||
|
author: devesh-chaudhari
|
||||||
|
command: rxjs-catch-error
|
||||||
|
contributors:
|
||||||
|
- Dinozavvvr
|
||||||
|
challengeNumber: 38
|
||||||
|
sidebar:
|
||||||
|
order: 14
|
||||||
|
---
|
||||||
|
|
||||||
|
## Информация
|
||||||
|
|
||||||
|
### Как использовать приложение
|
||||||
|
|
||||||
|
Наше приложение представляет собой форму с полем ввода текста и кнопкой "Получить". При нажатии на кнопку "Получить" данные извлекаются из [бесплатного API](https://jsonplaceholder.typicode.com/).
|
||||||
|
|
||||||
|
Корректные значения для успешного ответа ограничены следующим: posts, comments, albums, photos, todos и users. Любые другие значения приведут к ошибке.
|
||||||
|
|
||||||
|
### Ошибка
|
||||||
|
|
||||||
|
В нашем приложении обнаружена ошибка. Пользователи могут успешно получать данные только до тех пор, пока не будет отправлен недопустимый запрос. После получения ответа об ошибке пользователи не могут отправлять дополнительные запросы.
|
||||||
|
|
||||||
|
### Изучение
|
||||||
|
|
||||||
|
Это приложение предоставляет возможность понять правильное размещение оператора [`catchError`](https://rxjs.dev/api/operators/catchError). Если он размещен неправильно, вся подписка будет завершена, что предотвратит отправку дополнительных запросов. Цель состоит в том, чтобы сохранить общую подписку, правильно обрабатывая уведомления об ошибках от внутренних Observable.
|
||||||
|
|
||||||
|
## Утверждение
|
||||||
|
|
||||||
|
Цель - использовать оператор catchError для управления ошибками внутри вашего потока Rxjs.
|
||||||
|
|
||||||
|
## Ограничения
|
||||||
|
|
||||||
|
Пользователи должны иметь возможность журналировать значение/ошибку каждый раз при нажатии кнопки "Получить".
|
||||||
27
docs/src/content/docs/ru/challenges/testing/17-router.md
Normal file
27
docs/src/content/docs/ru/challenges/testing/17-router.md
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
---
|
||||||
|
title: 🟠 Роутер
|
||||||
|
description: Задача 17 посвящена тестрированию Роутера
|
||||||
|
author: thomas-laforge
|
||||||
|
contributors:
|
||||||
|
- Dinozavvvr
|
||||||
|
challengeNumber: 17
|
||||||
|
command: testing-router-outlet
|
||||||
|
sidebar:
|
||||||
|
order: 108
|
||||||
|
---
|
||||||
|
|
||||||
|
## Информация
|
||||||
|
|
||||||
|
У нас есть функциональное приложение, которое позволяет просматривать доступные книги для выдачи в библиотеке. Если книга, которую вы ищете, доступна, вы будете перенаправлены на соответствующую книгу(и), в противном случае вы попадете на страницу ошибки.
|
||||||
|
|
||||||
|
Файл с именем `app.component.spec.ts` позволит вам тестировать ваше приложение с использованием библиотеки Testing Library. Чтобы запустить наборы тестов, вы должны выполнить команду `npx nx test testing-router-outlet`. Вы также можете установить [Jest Runner](https://marketplace.visualstudio.com/items?itemName=firsttris.vscode-jest-runner), чтобы выполнять тесты, щелкая на кнопку `Run` над каждым блоком `describe` или `it`.
|
||||||
|
|
||||||
|
Для тестирования с использованием Cypress вы будете выполнять свои тесты внутри файла `app.component.cy.ts` и запускать команду `npx nx component-test testing-router-outlet` для выполнения наборов тестов. Вы можете добавить флаг `--watch`, чтобы выполнять ваши тесты в режиме наблюдения.
|
||||||
|
|
||||||
|
# Задание
|
||||||
|
|
||||||
|
Цель - протестировать несколько поведений приложения, описанных в каждом тестовом файле, с использованием библиотеки Testing Library и Cypress Component Testing.
|
||||||
|
|
||||||
|
:::note
|
||||||
|
Я создал несколько блоков `it`, но вы можете добавить больше тестов, если хотите.
|
||||||
|
:::
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
---
|
||||||
|
title: 🟠 Вложенные компоненты
|
||||||
|
description: Задание 18 посвящено тестированию вложенных компонентов
|
||||||
|
author: thomas-laforge
|
||||||
|
contributors:
|
||||||
|
- Dinozavvvr
|
||||||
|
challengeNumber: 18
|
||||||
|
command: testing-nested
|
||||||
|
sidebar:
|
||||||
|
order: 109
|
||||||
|
---
|
||||||
|
|
||||||
|
## Информация
|
||||||
|
|
||||||
|
У нас есть небольшое приложение, которое отправляет заголовок, введенный в поле ввода, на фейковый бэкэнд.
|
||||||
|
Если заголовок введен правильно, вы можете отправить запрос, в противном случае вы получите ошибку, и запрос не будет отправлен.
|
||||||
|
Приложение создано с использованием <b>вложенных компонентов</b>. `ChildComponent` - это контейнер, который включает в себя четыре компонента: `ResultComponent`, `ButtonComponent`, `InputComponent` и `ErrorComponent`. Однако, поскольку мы тестируем наш компонент как черный ящик, архитектура наших компонентов ничего не меняет. Вы можете создавать свои тесты, изменять структуру компонентов, и ваши тесты должны по-прежнему проходить. Вот цель интеграционных тестов. <b>Никогда не тестируйте внутренние детали реализации!!!</b>.
|
||||||
|
|
||||||
|
Вы можете поиграть с ним, запустив: `npx nx serve testing-nested`.
|
||||||
|
|
||||||
|
Файл с именем `child.component.spec.ts` позволит вам тестировать ваше приложение с использованием библиотеки Testing Library. Чтобы запустить наборы тестов, вы должны выполнить команду `npx nx test testing-nested`. Вы также можете установить [Jest Runner](https://marketplace.visualstudio.com/items?itemName=firsttris.vscode-jest-runner), чтобы выполнять тесты, щелкая на кнопку `Run` над каждым блоком `describe` или `it`.
|
||||||
|
|
||||||
|
Для тестирования с использованием Cypress вы будете выполнять свои тесты внутри файла `child.component.cy.ts` и запускать команду `npx nx component-test testing-nested` для выполнения наборов тестов. Вы можете добавить флаг `--watch`, чтобы выполнять ваши тесты в режиме наблюдения.
|
||||||
|
|
||||||
|
# Задание
|
||||||
|
|
||||||
|
Цель - протестировать несколько поведений приложения, описанных в каждом тестовом файле, с использованием библиотеки Testing Library и Cypress Component Testing.
|
||||||
|
|
||||||
|
:::note
|
||||||
|
Я создал несколько блоков `it`, но вы можете добавить больше тестов, если хотите.
|
||||||
|
:::
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
---
|
||||||
|
title: 🟠 Ввод Вывод
|
||||||
|
description: Задача 19 посвящена тестированию Ввода и Вывода
|
||||||
|
author: thomas-laforge
|
||||||
|
contributors:
|
||||||
|
- Dinozavvvr
|
||||||
|
challengeNumber: 19
|
||||||
|
command: testing-input-output
|
||||||
|
sidebar:
|
||||||
|
order: 110
|
||||||
|
---
|
||||||
|
|
||||||
|
## Информация
|
||||||
|
|
||||||
|
У нас есть небольшое приложение-счетчик, которое увеличивает или уменьшает число. `CounterComponent` принимает начальное значение в качестве `@Input` и отправляет результат счетчика как `@Output`, когда мы нажимаем на кнопку **Send**. Поскольку мы тестируем наш компонент как черный ящик, у нас есть доступ только к нашим входным данным и мы слушаем выходные значения. <b>Не следует полагаться на внутренние детали реализации!!!</b>
|
||||||
|
|
||||||
|
Вы можете поиграть с ним, запустив: `npx nx serve testing-input-output`.
|
||||||
|
|
||||||
|
Файл с именем `counter.component.spec.ts` позволит вам протестировать ваше приложение с использованием библиотеки Testing Library. Чтобы запустить наборы тестов, вы должны выполнить команду `npx nx test testing-input-output`. Вы также можете установить [Jest Runner](https://marketplace.visualstudio.com/items?itemName=firsttris.vscode-jest-runner), чтобы выполнять тесты, щелкая на кнопку `Run` над каждым блоком `describe` или `it`.
|
||||||
|
|
||||||
|
Для тестирования с использованием Cypress вы будете выполнять свои тесты внутри файла `child.component.cy.ts` и запускать команду `npx nx component-test testing-input-output` для выполнения наборов тестов. Вы можете добавить флаг `--watch`, чтобы выполнять ваши тесты в режиме наблюдения.
|
||||||
|
|
||||||
|
# Задание
|
||||||
|
|
||||||
|
Цель - протестировать несколько поведений приложения, описанных в каждом тестовом файле, с использованием библиотеки Testing Library и Cypress Component Testing.
|
||||||
|
|
||||||
|
:::note
|
||||||
|
Я создал несколько блоков `it`, но вы можете добавить больше тестов, если хотите.
|
||||||
|
:::
|
||||||
33
docs/src/content/docs/ru/challenges/testing/20-modal.md
Normal file
33
docs/src/content/docs/ru/challenges/testing/20-modal.md
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
---
|
||||||
|
title: 🟠 Модальное окно
|
||||||
|
description: Задача 20 посвящена тестированию Модальных окн
|
||||||
|
author: thomas-laforge
|
||||||
|
contributors:
|
||||||
|
- Dinozavvvr
|
||||||
|
challengeNumber: 20
|
||||||
|
command: testing-modal
|
||||||
|
sidebar:
|
||||||
|
order: 111
|
||||||
|
---
|
||||||
|
|
||||||
|
## Информация
|
||||||
|
|
||||||
|
В этом небольшом приложении у вас есть поле ввода, в котором вы должны ввести имя, и кнопка **Confirm** для отправки формы.
|
||||||
|
Если вы вводите имя, появится модальное окно подтверждения; в противном случае будет отображено модальное окно с ошибкой.
|
||||||
|
В модальном окне подтверждения, если пользователь нажимает кнопку **Confirm**, появится сообщение с подтверждением отправки формы. Если пользователь нажимает **Cancel**, будет отображено сообщение об ошибке.
|
||||||
|
|
||||||
|
Цель этой задачи - протестировать модальные окна внутри вашего приложения. Для этого мы будем тестировать всё приложение, как это делает end-to-end тест. Это означает, что мы будем тестировать `AppComponent` как черный ящик и реагировать на события на странице. <b>Не следует тестировать внутренние детали</b>. Разница между e2e тестом и интеграционным тестом заключается в том, что мы будем подделывать все вызовы API. _(Все http-запросы фальсифицированы внутри этого приложения и отличаются от тех что присутствуют в реальном корпоративном приложении.)_
|
||||||
|
|
||||||
|
Вы можете поиграть с этим, запустив: `npx nx serve testing-modal`.
|
||||||
|
|
||||||
|
Файл с именем `app.component.spec.ts` позволит вам тестировать ваше приложение с использованием библиотеки Testing Library. Чтобы запустить наборы тестов, вы должны выполнить команду `npx nx test testing-modal`. Вы также можете установить [Jest Runner](https://marketplace.visualstudio.com/items?itemName=firsttris.vscode-jest-runner), чтобы выполнять тесты, щелкая на кнопку `Run` над каждым блоком `describe` или `it`.
|
||||||
|
|
||||||
|
Для тестирования с использованием Cypress вы будете выполнять свои тесты внутри файла `app.component.cy.ts` и запускать команду `npx nx component-test testing-modal` для выполнения наборов тестов. Вы можете добавить флаг `--watch`, чтобы выполнять ваши тесты в режиме наблюдения.
|
||||||
|
|
||||||
|
# Задание
|
||||||
|
|
||||||
|
Цель - протестировать несколько поведений приложения, описанных в каждом тестовом файле, с использованием библиотеки Testing Library и Cypress Component Testing.
|
||||||
|
|
||||||
|
:::note
|
||||||
|
Я создал несколько блоков `it`, но вы можете добавить больше тестов, если хотите.
|
||||||
|
:::
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
---
|
||||||
|
title: 🟠 Создание harness класса
|
||||||
|
description: Задача 24 посвящено созданию компонента тестового стенда.
|
||||||
|
author: thomas-laforge
|
||||||
|
contributors:
|
||||||
|
- Dinozavvvr
|
||||||
|
challengeNumber: 24
|
||||||
|
command: testing-create-harness
|
||||||
|
sidebar:
|
||||||
|
order: 112
|
||||||
|
---
|
||||||
|
|
||||||
|
## Информация
|
||||||
|
|
||||||
|
Цель этой задачи - реализовать harness класс для `slider.component.ts`. Файл стенда, `slider.harness.ts`, уже создан.
|
||||||
|
|
||||||
|
Необходимо реализовать следующее API:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
async clickPlus(): Promise<void> ;
|
||||||
|
|
||||||
|
async clickMinus(): Promise<void>;
|
||||||
|
|
||||||
|
async getValue(): Promise<number> ;
|
||||||
|
|
||||||
|
async getMinValue(): Promise<number>;
|
||||||
|
|
||||||
|
async disabled(): Promise<boolean>;
|
||||||
|
|
||||||
|
async setValue(value: number): Promise<void>;
|
||||||
|
```
|
||||||
|
|
||||||
|
Кроме того, вы должны создать `HarnessPredicate` с предикатом по умолчанию и свойством `minValue`.
|
||||||
|
|
||||||
|
```ts
|
||||||
|
static with<T extends MySliderHarness>(
|
||||||
|
this: ComponentHarnessConstructor<T>,
|
||||||
|
options: SliderHarnessFilters = {}
|
||||||
|
): HarnessPredicate<T>;
|
||||||
|
```
|
||||||
|
|
||||||
|
Наконец, вам нужно создать набор тестов для `app.component`. Некоторые тесты по умолчанию уже написаны, но не стесняйтесь добавлять столько тестов, сколько вам нужно, и создавать столько методов, сколько вам потребуется.
|
||||||
|
|
||||||
|
> Документация Angular Material доступна [здесь](https://material.angular.io/cdk/test-harnesses/overview).
|
||||||
|
|
||||||
|
Удачи !!! 💪
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
---
|
||||||
|
title: 🔴 Приложение из реальной жизни
|
||||||
|
description: Задача 29 посвящена тестированию приложения из реальной жизни
|
||||||
|
author: thomas-laforge
|
||||||
|
contributors:
|
||||||
|
- Dinozavvvr
|
||||||
|
challengeNumber: 29
|
||||||
|
command: testing-todos-list
|
||||||
|
sidebar:
|
||||||
|
order: 205
|
||||||
|
---
|
||||||
|
|
||||||
|
## Информация
|
||||||
|
|
||||||
|
Это приложение представляет собой большой вызов, потому что оно тесно напоминает приложение из реальной жизни, с которым вы можете столкнуться в своей повседневной деятельности в качестве разработчика Angular. Что делает его более сложным, так это необходимость обрабатывать асинхронные задачи и создавать соответствующие заглушки.
|
||||||
|
|
||||||
|
Приложение - это типичное приложение для списка задач. Вы можете фильтровать заявки, создавать новые, назначать каждую заявку, закрывать другие и переходить к деталям каждой заявки.
|
||||||
|
|
||||||
|
В этом вызове вы напишете тесты для `ListComponent`, который представляет глобальный вид, и `RowComponent`, который представляет конкретную заявку. Кроме того, вам нужно будет написать модульные тесты для `TicketStoreService`, используя библиотеку Testing Library. _Эта библиотека позволяет эффективно тестировать сервисы._
|
||||||
|
|
||||||
|
Особенно сложно будет обрабатывать асинхронные задачи. Важно не вводить явные <b>ожидания(waits)</b> в ваши тесты, так как это приведет к ненужным задержкам. Вместо этого лучше искать элемент, который должен появиться или исчезнуть из DOM. В этом случае тест будет естественным образом ожидать правильного периода времени, так как ожидания уже реализованы в обеих библиотеках. Воспользуйтесь встроенными функциональными возможностями для создания эффективных и надежных тестов.
|
||||||
|
|
||||||
|
Вы можете поиграть с этим, запустив: `npx nx serve testing-todos-list`.
|
||||||
|
|
||||||
|
Чтобы запустить тесты Testing Library, вам нужно выполнить `npx nx test testing-todos-list`. Вы также можете установить [Jest Runner](https://marketplace.visualstudio.com/items?itemName=firsttris.vscode-jest-runner), чтобы выполнять тесты, нажимая на кнопку `Run` над каждым блоком `describe` или `it`.
|
||||||
|
|
||||||
|
Для тестирования с помощью Cypress вы выполните свой тест внутри `child.component.cy.ts` и выполните `npx nx component-test testing-todos-list`, чтобы запустить ваши тестовые наборы. Вы можете добавить флаг `--watch`, чтобы выполнять тесты в режиме наблюдения.
|
||||||
|
|
||||||
|
# Задание
|
||||||
|
|
||||||
|
Цель - протестировать множество поведений приложения, описанных в каждом тестовом файле, с использованием библиотеки Testing и Cypress Component Testing.
|
||||||
|
|
||||||
|
:::note
|
||||||
|
Я создал несколько блоков `it`, но не стесняйтесь добавлять больше тестов, если хотите.
|
||||||
|
:::
|
||||||
73
docs/src/content/docs/ru/challenges/testing/index.mdx
Normal file
73
docs/src/content/docs/ru/challenges/testing/index.mdx
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
---
|
||||||
|
title: Тестирование
|
||||||
|
prev: false
|
||||||
|
next: false
|
||||||
|
contributors:
|
||||||
|
- Dinozavvvr
|
||||||
|
description: Введение в задачи по тестированию.
|
||||||
|
noCommentSection: true
|
||||||
|
sidebar:
|
||||||
|
order: 1
|
||||||
|
---
|
||||||
|
|
||||||
|
import { LinkCard } from '@astrojs/starlight/components';
|
||||||
|
|
||||||
|
Тестирование - это важный этап в создании масштабируемых, поддерживаемых и надежных приложений.
|
||||||
|
Тестирование никогда не должно быть упущено, даже в случае сжатых сроков или сильного давления со стороны команды продукта.
|
||||||
|
В наши дни существует множество замечательных инструментов, которые облегчают тестирование вашего кода и обеспечивают отличный опыт разработчика.
|
||||||
|
|
||||||
|
В этой серии упражнений по тестированию мы изучим и освоим [Testing Library](https://testing-library.com/docs/) и [Cypress Component Testing](https://docs.cypress.io/guides/component-testing/angular/overview), которые упрощают манипуляции с DOM для тестирования любого компонента Angular.
|
||||||
|
|
||||||
|
Преимущества использования <b>Testing Library</b> или <b>Cypress Component Testing</b> заключаются в том, что вы тестируете свой компонент как черный ящик. Вы будете взаимодействовать только с тем, что пользователь может делать на интерфейсе. Однако отличие от полноценных тестов заключается в том, что бэкэнд замокан, что делает тесты быстрее и более поддерживаемыми.
|
||||||
|
Цель состоит в том, чтобы мокать как можно меньше, чтобы тестировать ваш компонент на более высоком уровне, чем при модульном тестировании, что облегчит рефакторинг.
|
||||||
|
В реальном приложении интеграционные тесты - это тесты, которые вы будете писать больше всего. Изучение того, как их писать, сделает ваше приложение более надежным и поддерживаемым.
|
||||||
|
|
||||||
|
Перед вами серия из 8 задач, которые вы можете решить в любом порядке.
|
||||||
|
|
||||||
|
<LinkCard
|
||||||
|
title="🟢 Harness"
|
||||||
|
description="Узнайте, как тестировать с использованием компонентов Angular CDK harness"
|
||||||
|
href="/challenges/testing/23-harness/"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<LinkCard
|
||||||
|
title="🟢 Checkbox"
|
||||||
|
description="Узнайте, как отлаживать ваши тесты с помощью Testing Library на простом приложении с флажками"
|
||||||
|
href="/challenges/testing/28-checkbox/"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<LinkCard
|
||||||
|
title="🟠 Router"
|
||||||
|
description="Узнайте, как тестировать компоненты маршрутизатора"
|
||||||
|
href="/challenges/testing/17-router/"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<LinkCard
|
||||||
|
title="🟠 Nested Components"
|
||||||
|
description="Узнайте, как тестировать вложенные компоненты"
|
||||||
|
href="/challenges/testing/18-nested-comp/"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<LinkCard
|
||||||
|
title="🟠 Input Output"
|
||||||
|
description="Узнайте, как тестировать вводы и выводы"
|
||||||
|
href="/challenges/testing/19-input-output/"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<LinkCard
|
||||||
|
title="🟠 Modal"
|
||||||
|
description="Узнайте, как тестировать модальный компонент"
|
||||||
|
href="/challenges/testing/20-modal/"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<LinkCard
|
||||||
|
title="🟠 Harness Creation"
|
||||||
|
description="Узнайте, как создать собственные харнесы для ваших компонентов"
|
||||||
|
href="/challenges/testing/24-harness-creation/"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<LinkCard
|
||||||
|
title="🔴 Реальное приложение"
|
||||||
|
description="Узнайте, как написать серию тестов для реальных приложений"
|
||||||
|
href="/challenges/testing/29-real-application/"
|
||||||
|
/>
|
||||||
@@ -21,5 +21,7 @@
|
|||||||
"subscription.note.title": "Notes",
|
"subscription.note.title": "Notes",
|
||||||
"subscription.note.description": "This email will only be used for sending new challenges updates",
|
"subscription.note.description": "This email will only be used for sending new challenges updates",
|
||||||
"contributor.title": "Contributors",
|
"contributor.title": "Contributors",
|
||||||
"contributor.subtitle": "Thanks to all the contributors who have helped make this documentation better!"
|
"contributor.subtitle": "Thanks to all the contributors who have helped make this documentation better!",
|
||||||
|
"sponsors.description": "Big thanks to the people supporting this project: ",
|
||||||
|
"sponsors.joinButton": "Join the list"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,5 +61,7 @@
|
|||||||
"subscription.note.title": "Notas",
|
"subscription.note.title": "Notas",
|
||||||
"subscription.note.description": "Este correo se utilizará para informar acerca de nuevos retos",
|
"subscription.note.description": "Este correo se utilizará para informar acerca de nuevos retos",
|
||||||
"contributor.title": "Contributors",
|
"contributor.title": "Contributors",
|
||||||
"contributor.subtitle": "Thanks to all the contributors who have helped make this documentation better!"
|
"contributor.subtitle": "Thanks to all the contributors who have helped make this documentation better!",
|
||||||
|
"sponsors.description": "Big thanks to the people supporting this project: ",
|
||||||
|
"sponsors.joinButton": "Join the list"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,5 +21,7 @@
|
|||||||
"subscription.note.title": "Notes",
|
"subscription.note.title": "Notes",
|
||||||
"subscription.note.description": "This email will only be used for sending new challenges updates",
|
"subscription.note.description": "This email will only be used for sending new challenges updates",
|
||||||
"contributor.title": "Contributors",
|
"contributor.title": "Contributors",
|
||||||
"contributor.subtitle": "Thanks to all the contributors who have helped make this documentation better!"
|
"contributor.subtitle": "Thanks to all the contributors who have helped make this documentation better!",
|
||||||
|
"sponsors.description": "Big thanks to the people supporting this project: ",
|
||||||
|
"sponsors.joinButton": "Join the list"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,5 +22,7 @@
|
|||||||
"subscription.note.title": "Notas",
|
"subscription.note.title": "Notas",
|
||||||
"subscription.note.description": "Este email será apenas usado para enviar atualizações de novos desafios",
|
"subscription.note.description": "Este email será apenas usado para enviar atualizações de novos desafios",
|
||||||
"contributor.title": "Contributors",
|
"contributor.title": "Contributors",
|
||||||
"contributor.subtitle": "Thanks to all the contributors who have helped make this documentation better!"
|
"contributor.subtitle": "Thanks to all the contributors who have helped make this documentation better!",
|
||||||
|
"sponsors.description": "Muito obrigado as pessoas que apoiam este projeto: ",
|
||||||
|
"sponsors.joinButton": "Juntar-se à lista"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,5 +22,7 @@
|
|||||||
"subscription.note.title": "Примечание",
|
"subscription.note.title": "Примечание",
|
||||||
"subscription.note.description": "Этот email будет использоваться только для сообщений о новых испытаниях",
|
"subscription.note.description": "Этот email будет использоваться только для сообщений о новых испытаниях",
|
||||||
"contributor.title": "Контрибьюторы",
|
"contributor.title": "Контрибьюторы",
|
||||||
"contributor.subtitle": "Спасибо всем контрибьюторам которые помогли сделать эту документацию лучше!"
|
"contributor.subtitle": "Спасибо всем контрибьюторам которые помогли сделать эту документацию лучше!",
|
||||||
|
"sponsors.description": "Big thanks to the people supporting this project: ",
|
||||||
|
"sponsors.joinButton": "Join the list"
|
||||||
}
|
}
|
||||||
|
|||||||
1543
package-lock.json
generated
1543
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user