Перевод статьи «Streamlining Playwright Visual Regression Testing with GitHub Actions».
В компании, где я сейчас работаю, изначально визуальное регрессионное тестирование дизайн системы не проводилось. Когда я внедрил снапшот-тесты на Playwright, мы довольно быстро столкнулись с проблемой: локально мы запускали снапшоты на macOS (darwin), но наш CI использовал Linux. Это несоответствие означало, что снимки на локальной машине и в CI отличались, и было трудно поддерживать согласованность.
Проблема: разница снапшотов на Mac и Linux
В команде мы ведём разрабку на машинах с macOS, соответственно, локальные снимки постоянно генерировались на этой платформе. Однако, наша среда CI работала на Linux, что приводило к отличиям в генерируемых снапшотах. Мы столкнулись с массой проблем на этапе сравнения снапшотов между собой — они не совпадали.
Более подробно эта проблема описана в статье Тони Уорда «Пришло время разрушить визуальное регрессионное тестирование «.
Мы изучили два возможных решения:
- Запуск Docker локально и в CI: это обеспечит использование одного базового образа в обеих средах. Однако, для нас это было неприменимо из-за лицензионных ограничений и высокого порога входа, которого такое решение привнесло бы.
- CI как источник истины: Можно использовать CI для поддержки наших снапшотов, в таком случае CI будет генерировать и утверждать снимки, обеспечивая их согласованность и стабильность.
В конечном итоге мы выбрали второй вариант. Таким образом наш CI пайплайн будет заниматься созданием, проверкой и утверждением снапшотов, что позволит достигнуть единый процесс для всей нашей команды.
Друзья, поддержите нас вступлением в наш телеграм канал QaRocks. Там много туториалов, задач по автоматизации и книг по QA.
Решение: CI управляет снапшотами
Для этого я создал два GitHub Actions, чтобы обеспечить бесперебойный процесс запуска Playwright тестов и обновления снапшотов. Это решает проблему несоответствия платформ и в тоже время автоматизирует процесс утверждения снапшотов.
Ниже описан перечень моих действий.
Действие 1: Запуск Playwright тестов и сравнение с эталоном
Первый GitHub Action запускает Playwright тесты и проверяет логи на наличие проблем со снапшотами (отсутствующие или несовпадающие снапшоты). Если проблема есть, он публикует комментарий к пул реквесту (PR) со ссылкой на отчет Playwright, чтобы инженеры могли посмотреть различия.
Код для первого GitHub Action:
name: Playwright Tests
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
playwright:
timeout-minutes: 60
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: lts/*
- name: Install dependencies
run: npm install -g pnpm && pnpm install
- name: Install Playwright Browsers
run: pnpm exec playwright install --with-deps
- name: Run Playwright tests
run: |
pnpm exec playwright test | tee output.log
if grep -q -e "Error: A snapshot doesn't exist at" -e "Screenshot comparison failed" output.log; then
echo "Playwright tests failed due to a snapshot issue."
echo "SNAPSHOT_DIFFERENCES=true" >> $GITHUB_ENV
exit 1
elif grep -q "failed" output.log; then
echo "Playwright tests failed due to a non-snapshot issue."
exit 1
fi
- uses: actions/upload-artifact@v4
id: artifact-upload
if: always()
with:
name: playwright-report
path: playwright-report/
retention-days: 30
- name: Comment on PR with report link
uses: thollander/actions-comment-pull-request@v3
if: ${{ failure() && env.SNAPSHOT_DIFFERENCES == 'true' }}
with:
message: |
### Playwright visual snapshot differences were detected.
View the [Playwright report](${{ steps.artifact-upload.outputs.artifact-url }}) to review the visual differences.
**To approve the snapshot changes and update the snapshots, please comment:** /approve-snapshots
Давайте разберем основные этапы кода:
1. Запуск Playwright тестов
На этом шаге выполняются Playwright тесты и логируется результат с помощью команды pnpm exec playwright test | tee output.log. Мы также проверяем логи на наличие специфических ошибок, таких как пропущенные снапшоты или ошибки сравнения. Если обнаружена любая из этих проблем, то переменной окружения присваивается SNAPSHOT_DIFFERENCES=true и процесс завершается с кодом ошибки. Очень важно определить причину падания теста — из-за снапшота или чего-то другого.
2. Загрузка артефактов
- uses: actions/upload-artifact@v4
id: artifact-upload
if: always()
with:
name: playwright-report
path: playwright-report/
retention-days: 30
На этом шаге результаты тестирования в виде HTML-отчета, сгенерированного Playwright, загружаются в качестве артефакта GitHub. Таким образом отчёт можно скачать и проанализировать с помощью GitHub Actions UI. В отчете представлены визуальные различия всех снапшотов, что помогает инженерам определить и изучить суть проблемы.
3. Комментарий к PR со ссылкой на отчет
- name: Comment on PR with report link
uses: thollander/actions-comment-pull-request@v3
if: ${{ failure() && env.SNAPSHOT_DIFFERENCES == 'true' }}
with:
message: |
### Playwright visual snapshot differences were detected.
View the [Playwright report](${{ steps.artifact-upload.outputs.artifact-url }}) to review the visual differences.
Если находится разница в снапшотах, этот шаг добавляет комментарий к PR, указывая там ссылку на загруженный Playwright отчёт. Соответственно, коллега, который будет ревьить PR, получает упрощённый и быстрый доступ к отчету, просмотр визуальных различий и принятие решения об одобрении или отклонении изменений.

Действие 2: Обновление снапшотов в комментариях
Когда инженер просмотрит визуальные различия и решит, что обновленные снапшоты верны, он может добавить комментарий /approve-snapshots в PR. Это запустит второй GitHub Action, который автоматически обновит снапшоты, закомитит изменения и запушит их в ветку.

Код для второго GitHub Action:
name: Update Snapshots on Comment
on:
issue_comment:
types: [created]
jobs:
update-snapshots:
name: Update Snapshots
if: github.event.issue.pull_request && contains(github.event.comment.body, '/approve-snapshots')
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- name: Get branch of PR
uses: xt0rted/pull-request-comment-branch@v2
id: comment-branch
- name: Checkout PR branch
uses: actions/checkout@v4
with:
ref: ${{ steps.comment-branch.outputs.head_ref }}
- name: Comment action started
uses: thollander/actions-comment-pull-request@v3
with:
message: |
### Updating snapshots. Click [here](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}) to see the status.
- uses: actions/setup-node@v4
with:
node-version: lts/*
- name: Install dependencies
run: npm install -g pnpm && pnpm install
- name: Install Playwright Browsers
run: pnpm exec playwright install --with-deps
- name: Run Playwright update snapshots
run: pnpm exec playwright test --update-snapshots
- name: Commit and push updated snapshots
uses: stefanzweifel/git-auto-commit-action@v5
with:
commit_message: 'Update e2e snapshots'
- name: Comment success
uses: thollander/actions-comment-pull-request@v3
with:
message: |
### 🎉 Successfully updated and committed Playwright snapshots! 🎉
Теперь давайте разберем ключевые шаги в этом действии:
1. Запуск проверки на соответствие условию
if: github.event.issue.pull_request && contains(github.event.comment.body, '/approve-snapshots')
Это условие гарантирует, что действие будет запущено только в том случае, если в теле комментария содержится текст /approve-snapshots и событие связано с pull request. Таким образом, мы отсеиваем нерелевантные комментарии и гарантируем, что только правильный триггер запускает действие.
2. Получить ветку PR’а
- name: Get branch of PR uses: xt0rted/pull-request-comment-branch@v2 id: comment-branch
На этом шаге находится ветка, связанная с PR, в которой был сделан комментарий. Действию необходимо знать ветку для её чек-аута, поскольку именно в ней будет происходить обновление снапшота.
3. Чек-аут ветки PR
- name: Checkout PR branch
uses: actions/checkout@v4
with:
ref: ${{ steps.comment-branch.outputs.head_ref }}
Здесь мы чек-аутим ветку, связанную с PR. Это гарантирует, что снапшоты будут обновлены в правильной ветке (а не в мейне), сохраняя изменения, относящиеся к текущей функции или исправлению, над которым ведется работа.
4. Комментарий начала action
- name: Comment action started
uses: thollander/actions-comment-pull-request@v3
with:
message: |
### Updating snapshots. Click [here](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}) to see the status.
Как только действие начинается, он публикует комментарий к PR, чтобы сообщить ревьюерам о том, что снапшоты обновляются, и предоставляет ссылку на лог GitHub Actions.

5. Запустите обновленияснапшотов в Playwright
- name: Run Playwright update snapshots run: pnpm exec playwright test --update-snapshots
На этом шаге повторно запускаются Playwright тесты, но с флагом --update-snapshots. При этом обновляются все снапшоты, которые ранее были отмечены как «отличающиеся» во время первоначального запуска теста.
6. Сделайте комит и пуш обновленных снапшотов
- name: Commit and push updated snapshots
uses: stefanzweifel/git-auto-commit-action@v5
with:
commit_message: 'Update e2e snapshots'
После обновления снапшотов этот шаг фиксирует новые снапшоты и автоматически переносит изменения в ветку PR.

7. Комментарий про успешный апдейт
- name: Comment success
uses: thollander/actions-comment-pull-request@v3
with:
message: |
### 🎉 Successfully updated and committed Playwright snapshots! 🎉
Наконец, действие публикует комментарий об успехе в PR, сообщая команде, что снапшоты были успешно обновлены и закомичены.

Заключение
Переложив ответственность за создание снапшотов на CI, мы смогли устранить несоответствия платформ, которые мешали нам в момент настройки визуального регрессионного тестирования. Два GitHub Actions оптимизировали наш рабочий процесс, автоматизировав Playwright тесты и процесс коммита снапшотов. Теперь у инженеров есть четкий и последовательный способ ревьюить, апрувить и обновлять снапшоты непосредственно из pull request’ов, обеспечивая визуальную стабильность нашей дизайн-системы во всех средах.
Этот новый подход не только помог нам повысить эффективность тестирования, но и дал уверенность в том, что наши визуальные тесты надежны и последовательны, независимо от того, кто их проводит и в какой среде они работают.
Для практической демонстрации этой настройки вы можете посмотреть это репо с запросом на выгрузку, в котором показан весь процесс, от запуска тестов Playwright до апрува обновлений снапшотов.
Огромная благодарность!
Я хочу выразить огромную благодарность двум инженерам из другой компании, Тони и Клинтону, за то, что они также столкнулись с этой проблемой со снапшотами в CI и вместе со мной разработали это решение. Это сотрудничество помогло нам выработать чистый и автоматизированный подход, и мы надеемся, что он поможет другим людям, которые могут столкнуться с такой же проблемой. ❤️
