Skip to content

Пиксельные снимки для теней, пунктира и форм - #131

Merged
ichiesov merged 1 commit into
storybook-a11y-checksfrom
storybook-pixel-snapshots
Aug 27, 2026
Merged

Пиксельные снимки для теней, пунктира и форм#131
ichiesov merged 1 commit into
storybook-a11y-checksfrom
storybook-pixel-snapshots

Conversation

@khaliulin

@khaliulin khaliulin commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Стекнут на #130. Порядок мержа: #127#128#129#130#131.

Какой аддон

Никакой — аддона не ставим. Единственный настоящий аддон визуальной регрессии, живой на Storybook 10, это @chromatic-com/storybook, но он гонит все 264 stories на серверы Chromatic. Для внутреннего кита это вопрос к безопасности, а не техническое решение, поэтому взял локальный jest-image-snapshot@6.5.2 — он встраивается в тот же postVisit, ничего не отправляет наружу и не требует новой инфраструктуры.

storycap/reg-suit и loki мертвы (последние релизы 2024, peer на Storybook 7/8), @percy/storybook тянет react в peer — для Angular мимо.

Не вместо снапшотов стилей, а поверх

Пиксели включены точечно, только там, где вычисленные стили ничего не говорят о внешнем виде:

компонент что ловит
card тень
divider пунктир (border-style не в списке отслеживаемых)
avatar форма, обрезка изображения
skeleton градиент
badge, tag, chip форма и иконка внутри

Итого 39 снимков. Остальные 222 story остаются на снапшотах стилей — они дешевле, читаемее и не привязаны к ОС.

Включается на уровне meta:

parameters: { pixelSnapshot: true }

Анимации перед съёмкой замораживаются (animation: none), иначе скелетон и спиннер дают случайный кадр.

Две грабли, которые пришлось обойти

Зависание на разделителе. locator('#storybook-root').screenshot() висел ровно 30 с на Divider / Default и TypeDashed: у горизонтального разделителя корень имеет нулевую высоту (линию рисует ::before), а Playwright ждёт, пока элемент станет видимым. Теперь область снимка считается сама — объединение прямоугольников корня и всех потомков плюс 4 px, и снимается обычным клипом. Разделитель попадает в кадр 1256×22.

Аватары с картинками. Три story расходились стабильно на 1.5 % (870 пикселей): img.complete означает «загружена», но не «раскодирована и отрисована». Добавлен img.decode() перед съёмкой.

Baseline не хранится в репозитории

Пиксельный baseline привязан к ОС: снимки сделаны на macOS, на Linux в CI рендер шрифтов другой и они не совпадут. Общий baseline не подошёл бы ни там, ни там, поэтому в git его нет — весь каталог .storybook/pixel-baselines/ (вместе с diff-картинками падений) в .gitignore.

Первый локальный прогон создаёт снимки сам, дальше сверяется с ними. Проверено на разделителе: после удаления его семи снимков прогон даёт 7 snapshots written, повторный — 7 snapshots passed.

Если слой решим включать в пайплайн, генерацию и сверку надо гонять в одном окружении — в CI это образ mcr.microsoft.com/playwright, и baseline пересобирается внутри него.

Проверка

  • baseline сгенерирован локально (39 PNG, вне git), два прогона подряд зелёные кроме Password из Исправить открывающий тег в шаблоне story Password #128: 1 failed, 263 passed, 35–40 с;
  • негативная проверка: подменил baseline у Tag / Default снимком бейджа — story упала, после возврата снова зелено.

@khaliulin
khaliulin force-pushed the storybook-a11y-checks branch from fb4c9c2 to d16f281 Compare August 26, 2026 12:41
@khaliulin
khaliulin force-pushed the storybook-pixel-snapshots branch from 98021af to 83f1d41 Compare August 26, 2026 12:41
@khaliulin

Copy link
Copy Markdown
Contributor Author

Переписал коммит: конфиг тест-раннера больше не протекает в stories. Опт-ины переехали в .storybook/test-runner.tsSTYLE_SNAPSHOT_SKIP (по id story) и PIXEL_SNAPSHOT_TITLES (по title компонента) вместо parameters.styleSnapshot.skip и parameters.pixelSnapshot в файлах stories.

Во всём стеке теперь ноль изменённых stories — только .storybook/, зависимости и .gitignore. Ветки перезалиты force-push, базы PR не менялись.

Проверка после переписывания: полный прогон 1 failed, 263 passed (падает только Password из #128), 39 пиксельных снимков на месте — поведение не изменилось.

@khaliulin
khaliulin force-pushed the storybook-pixel-snapshots branch from 83f1d41 to ef11e17 Compare August 26, 2026 17:37
@khaliulin

Copy link
Copy Markdown
Contributor Author

Убрал пиксельный baseline из репозитория — коммит ef11e17 (ветка перезалита force-push, база PR не менялась).

В Files changed теперь четыре файла: .gitignore, .storybook/test-runner.ts, package.json, package-lock.json. Ни одного PNG — ни в диффе, ни в истории ветки (git log --name-only main..HEAD | grep pixel-baselines → 0).

Весь каталог .storybook/pixel-baselines/ под игнором: baseline привязан к рендеру шрифтов в ОС, общий для macOS и CI не совпал бы ни там, ни там. Первый локальный прогон создаёт снимки сам.

Проверка: удалил семь снимков разделителя → 7 snapshots written, 7 passed (17.6 с), повторный прогон → 7 snapshots passed (4.0 с).

@ichiesov
ichiesov merged commit 65be132 into storybook-a11y-checks Aug 27, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants