-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
docs(storybook): add documentation about storybook
- Loading branch information
Showing
4 changed files
with
344 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
--- | ||
title: Скриншотное тестирование со Storybook | ||
slug: screenshot-testing-with-storybook | ||
hide_table_of_contents: false | ||
date: 2024-09-11T13:00 | ||
--- | ||
|
||
[Storybook][storybook] - это инструмент для разработки пользовательских интерфейсов на основе компонентов. Он позволяет разработчикам независимо визуализировать компоненты в различных состояниях в изолированной от остальных компонентов среде. | ||
Такой "шоурум" идеально подходит для скриншотного тестирования ваших компонентов, т.к. за счет этой изолированной среды такие тесты получаются в разы стабильнее и быстрее, чем вариант с e2e. | ||
|
||
С помощью плагина [@testplane/storybook][testplane-storybook] предоставляется возможность автоматически проверять изменения ваших компонентов с помощью скриншотного тестирования без единой строчки кода теста. | ||
Вам достаточно описать ваш компонент в `Storybook`, а `testplane` при запуске автоматически сгенерит все необходимые тесты, прогонит их в нужных браузерах и предоставит визуальный отчет для обновления скриншотов. | ||
При этом, если для компонентов была задекларирована [play-функция][play-function], то `testplane` перед началом теста выполнит ее, чтобы привести компонент в нужное состояние. | ||
|
||
Но если и этих возможностей вам не хватит, то вы можете прямо в story-файле описать testplane-тест, который будет выполнен как дополнительный тест для компонента. | ||
|
||
### Как использовать? | ||
|
||
Узнайте больше об этом в нашей документации <a href="/docs/v8/visual-testing/with-storybook">Скриншотное тестирование со Storybook</a>. | ||
|
||
[Пример проекта][example] с настроенным скриншотным тестированием со Storybook можно посмотреть в нашем репозитории на GitHub. | ||
|
||
[storybook][https://storybook.js.org] | ||
[testplane-storybook][https://github.com/gemini-testing/testplane-storybook] | ||
[play-function][https://storybook.js.org/docs/writing-stories/play-function] | ||
[example]: https://github.com/gemini-testing/testplane/examples/storybook-autoscreenshots |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
# Визуальное тестирование | ||
|
||
В testplane реализовано визуальное тестирование, с помощью которого пользователь может проверить визуальные изменения отдельного компонента, вьюпорта или всей страницы целиком. | ||
Для анализа тестов, сохранения/обновления измененных изображений и запуска тестов рекомендуется использовать плагин [html-reporter][html-reporter], который предоставляет удобный UI для всех действий. | ||
|
||
### Особенности сравнения скриншотов | ||
|
||
При вызове команды `assertView` осуществляется поиск нужного элемента на странице с его автоматическим ожиданием. По умолчанию перед снятием скриншота на странице будет отключена анимация, чтобы исключить в будущем нестабильность теста из-за изменяющегося состояния элемента. | ||
|
||
При сравнении учитываются следующие настройки: | ||
|
||
- мигающая каретка в текстовых инпутах игнорируется по умолчанию | ||
- на изображении игнорируются элементы, которые были указаны в опциях сравнения | ||
- учитываются настройки точности сравнения (допустимые отклонения) | ||
- учитываются настройки точности сравнения антиалиасинга для шрифтов (самый частый дифф на скриншотах) | ||
|
||
### Использование | ||
|
||
```typescript | ||
await browser.assertView(state, options); | ||
await browser.assertView(state, selector, options); | ||
await element.assertView(state, options); | ||
``` | ||
|
||
Команда `assertView` доступна как в контексте браузера, так и в контексте найденного элемента. Набор аргументов при этом отличается: | ||
|
||
```typescript | ||
it("check search view", async ({ browser }) => { | ||
// ... | ||
|
||
// taking screenshot of the current viewport | ||
await browser.assertView("viewport-screen"); | ||
|
||
// taking screenshot of a specific element (from the browser context) | ||
await browser.assertView("any-state-name", ".DocSearch", opts); | ||
|
||
const searchInput = await browser.$(".DocSearch"); | ||
await searchInput.click(); | ||
|
||
// taking screenshot of a previously found item (from the element context) | ||
await searchInput.assertView("any-state-name"); | ||
}); | ||
``` | ||
|
||
Подробнее о возможностях команды `assertView` читайте в соответствующих разделах. | ||
|
||
### Связанные команды | ||
|
||
- [browser.assertView][browser-command] | ||
- [element.assertView][element-command] | ||
|
||
[html-reporter]: ../../html-reporter/html-reporter-setup | ||
|
||
[looks-same]:[https://github.com/gemini-testing/looks-same] | ||
[browser-command]: https://testplane.io/docs/v8/commands/browser/assertView/ | ||
[element-command]: https://testplane.io/docs/v8/commands/element/assertView/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,256 @@ | ||
import Admonition from "@theme/Admonition"; | ||
|
||
# Скриншотное тестирование со Storybook | ||
|
||
[Storybook][storybook] - это инструмент для разработки пользовательских интерфейсов на основе компонентов. Он позволяет разработчикам независимо визуализировать компоненты в различных состояниях в изолированной от остальных компонентов среде. | ||
Такой "шоурум" идеально подходит для скриншотного тестирования ваших компонентов, т.к. за счет этой изолированной среды такие тесты получаются в разы стабильнее и быстрее, чем вариант с e2e. | ||
|
||
С помощью плагина [@testplane/storybook][testplane-storybook] предоставляется возможность автоматически проверять изменения ваших компонентов с помощью скриншотного тестирования. | ||
Вам достаточно описать ваш компонент в `Storybook`, а `testplane` при запуске автоматически сгенерит все необходимые тесты, прогонит их в нужных браузерах и предоставит визуальный отчет для обновления скриншотов. | ||
|
||
## Как использовать? {#how_to_use} | ||
|
||
### Шаг 1: Установка необходимых зависимостей | ||
|
||
Если в Вашем проекте еще нет `Testplane`, то рекомендуем ознакомиться с разделом [quickstart][quickstart] или выполнить в директории Вашего проекта команду ниже: | ||
|
||
```bash | ||
npm init testplane@latest | ||
``` | ||
|
||
Устанавливаем плагин для `testplane` | ||
|
||
```bash | ||
npm install @testplane/storybook --save-dev | ||
``` | ||
|
||
### Шаг 2: Настройка плагина | ||
|
||
Для работы плагина достаточно минимальной настройки - нужно просто объявить его в конфиге `testplane` без дополнительных опций: | ||
|
||
```typescript | ||
// .testplane.conf.ts | ||
export default { | ||
plugins: { | ||
"@testplane/storybook": {}, | ||
|
||
// other Testplane plugins... | ||
}, | ||
|
||
// other Testplane settings... | ||
}; | ||
``` | ||
|
||
### Шаг 3: Запуск тестов | ||
|
||
Для запуска storybook-тестов необходимо добавить опцию `--storybook`. Опция `--update-refs` позволяет сохранить/обновить эталонные изображения через CLI: | ||
|
||
```bash | ||
npx testplane --storybook --update-refs | ||
``` | ||
|
||
С помощью GUI-режима вы можете визуально оценить изменения в скриншотах, обновить их или перезапустить тесты: | ||
|
||
```bash | ||
npx testplane gui --storybook | ||
``` | ||
|
||
Если в Вашем проекте используется Storybook версии 6.x, то в настройках Storybook необходимо включить сохранение json-файла с Вашими историями: | ||
|
||
```typescript | ||
// .storybook/main.js | ||
export default { | ||
// ... | ||
features: { | ||
// ... | ||
buildStoriesJson: true, | ||
}, | ||
}; | ||
``` | ||
|
||
## Кастомные тесты {#custom_tests} | ||
|
||
Некоторые компоненты перед скриншотом нужно привести в какое-либо состояние. Для этого у сторибука есть сущность под названием [play-функция][play-function]. Если она определена, мы сначала выполним все action-ы из нее, и только после этого сделаем скриншот. | ||
Если вам не хватает выразительности Storybook, то вы можете в самой "Истории" описать testplane-тест, который будет выполнен как дополнительный тест для компонента. | ||
|
||
```typescript | ||
// stories/Primary.stories.ts | ||
import type { StoryObj } from "@storybook/react"; | ||
import type { WithTestplane } from "@testplane/storybook"; | ||
|
||
export const Primary: WithTestplane<StoryObj> = { | ||
args: { | ||
primary: true, | ||
label: "Button", | ||
}, | ||
testplane: { | ||
"my test": async ({ browser, expect }) => { | ||
const element = await browser.$(".storybook-button"); | ||
|
||
await expect(element).toHaveText("Button"); | ||
}, | ||
}, | ||
}; | ||
``` | ||
|
||
Также для теста можно добавить дополнительные настройки | ||
|
||
```typescript | ||
// stories/Primary.stories.ts | ||
import type { WithTestplane } from "@testplane/storybook"; | ||
import type { Meta, StoryObj } from "@storybook/react"; | ||
|
||
const meta: WithTestplane<Meta<typeof Button>> = { | ||
title: "Example/Button", | ||
component: Button, | ||
testplane: { | ||
skip: false, // if true, skips all Testplane tests from this story file | ||
autoscreenshotSelector: ".my-selector", // Custom selector to auto-screenshot elements | ||
browserIds: ["chrome"], // Testplane browsers to run tests from this story file | ||
assertViewOpts: { | ||
// override default assertView options for tests from this file | ||
ignoreDiffPixelCount: 5, | ||
}, | ||
}, | ||
}; | ||
|
||
export default meta; | ||
``` | ||
|
||
<Admonition type="warning"> | ||
При добавлении testplane-тестов расширение Ваших story-файлов должно быть `.js` или `.ts`. | ||
</Admonition> | ||
|
||
## Параметры конфигурации плагина | ||
|
||
<table> | ||
<thead> | ||
<tr> | ||
<td>**Параметр**</td> | ||
<td>**Тип**</td> | ||
<td>**По умолчанию**</td> | ||
<td>**Описание**</td> | ||
</tr> | ||
</thead> | ||
<tbody> | ||
<tr> | ||
<td>enabled</td> | ||
<td>`Boolean`</td> | ||
<td>true</td> | ||
<td>Включить / отключить плагин.</td> | ||
</tr> | ||
<tr> | ||
<td>storybookConfigDir</td> | ||
<td>`String`</td> | ||
<td>".storybook"</td> | ||
<td>Путь к директории конфигурационного файла Storybook.</td> | ||
</tr> | ||
<tr> | ||
<td>autoScreenshots</td> | ||
<td>`Boolean`</td> | ||
<td>true</td> | ||
<td>Включить / отключить авто матическое скриншотное тестирование (будут выполняться только вручную описанные tetplane-тесты)</td> | ||
</tr> | ||
<tr> | ||
<td>localport</td> | ||
<td>`Number`</td> | ||
<td>6006</td> | ||
<td>Порт для запуска dev-сервера Storybook.</td> | ||
</tr> | ||
<tr> | ||
<td>remoteStorybookUrl</td> | ||
<td>`String`</td> | ||
<td>""</td> | ||
<td>Урл удаленного Storybook. Если указан, то локальный dev-сервер Storybook не будет запущен.</td> | ||
</tr> | ||
<tr> | ||
<td>browserIds</td> | ||
<td>`Array<String | RegExp>`</td> | ||
<td>[]</td> | ||
<td>Массив id браузеров, в которых будут запущены тесты. По умолчанию тесты будут запущены во всех браузерах, описанных в конфиге testplane</td> | ||
</tr> | ||
</tbody> | ||
</table> | ||
|
||
Например, для запуска тестов на Storybook, опубликованном удаленно на `s3`, настройка будет выглядеть следующим образом: | ||
|
||
```typescript | ||
// .testplane.conf.ts | ||
export default { | ||
plugins: { | ||
"@testplane/storybook": { | ||
remoteStorybookUrl: "https://yastatic.net/s3/storybook/index.html", | ||
}, | ||
|
||
// other Testplane plugins... | ||
}, | ||
|
||
// other Testplane settings... | ||
}; | ||
``` | ||
|
||
## Дополнительные настройки {#extra_config} | ||
|
||
В Вашем проекте уже могут быть настроены другие типы тестирования, запускающиеся с помощью `testplane`. Чтобы не смешивать сущности, мы рекомендуем для storybook-тестов использовать отдельный конфиг и указывать его при запуске тестов. | ||
|
||
```bash | ||
npx testplane --storybook --config .testplane.storybook.conf.ts | ||
``` | ||
|
||
Сокращенная версия запуска | ||
|
||
```bash | ||
npx testplane --storybook -c .testplane.storybook.conf.ts | ||
``` | ||
|
||
Отдельный конфиг позволит Вам описать хранение скриншотов сторибуков рядом с Вашим story-файлом: | ||
|
||
```typescript | ||
// .testplane.storybook.conf.ts | ||
import path from "path"; | ||
import { getStoryFile } from "@testplane/storybook"; | ||
|
||
export default { | ||
screenshotsDir: test => { | ||
const relativeStoryFilePath = getStoryFile(test); | ||
const relativeStoryFileDirPath = path.dirname(relativeStoryFilePath); | ||
|
||
return path.join(relativeStoryFileDirPath, "screens", test.id, test.browserId); | ||
}, | ||
// other Testplane settings... | ||
}; | ||
``` | ||
|
||
В данном примере эталонные скриншоты будут сохранены в директории `screens/<testId>/<browserId>` относительно директории Вашего story-файла. | ||
|
||
## Оптимизация запуска тестов {#optimize_run} | ||
|
||
Storybook-тесты сами по себе довольно быстрые, т.к. для них не нужно сложное окружение, а на странице рендерится только один компонент. | ||
В контексте браузера 1 раз создается окружения для тестирования Storybook и переиспользуется от теста к тесту. Поэтому, для максимальной скорости прохождения тестов мы рекомендуем выставлять опцию [testsPerSession][tests-per-session] со значением не меньше 20, чтобы переиспользовать браузерную сессию как можно дольше: | ||
|
||
```typescript | ||
// .testplane.storybook.conf.ts | ||
export default { | ||
testsPerSession: 40, // set value for all browsers | ||
|
||
browsers: { | ||
"chrome-desktop": { | ||
testsPerSession: 50, // or set value for current browser | ||
}, | ||
firefox: { | ||
// ... | ||
}, | ||
}, | ||
|
||
// other Testplane settings... | ||
}; | ||
``` | ||
|
||
Также, для storybook-тестов будет проигнорирована опция [isolation][isolation], чтобы не пресоздавать окружение на каджый тест (это никак не влияет на стабильность тестов). | ||
|
||
[storybook]: [https://storybook.js.org] | ||
[testplane-storybook]: [https://github.com/gemini-testing/testplane-storybook] | ||
[play-function]: [https://storybook.js.org/docs/writing-stories/play-function] | ||
[quickstart]: ./quickstart/index | ||
[tests-per-session]: ./config/browsers/#tests_per_session | ||
[isolation]: ./config/browsers/#isolation |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters