Оптимизация визуального регрессионного тестирования Playwright с помощью GitHub Actions

Перевод статьи «Streamlining Playwright Visual Regression Testing with GitHub Actions».

В компании, где я сейчас работаю, изначально визуальное регрессионное тестирование дизайн системы не проводилось. Когда я внедрил снапшот-тесты на Playwright, мы довольно быстро столкнулись с проблемой: локально мы запускали снапшоты на macOS (darwin), но наш CI использовал Linux. Это несоответствие означало, что снимки на локальной машине и в CI отличались, и было трудно поддерживать согласованность.

Проблема: разница снапшотов на Mac и Linux

В команде мы ведём разрабку на машинах с macOS, соответственно, локальные снимки постоянно генерировались на этой платформе. Однако, наша среда CI работала на Linux, что приводило к отличиям в генерируемых снапшотах. Мы столкнулись с массой проблем на этапе сравнения снапшотов между собой — они не совпадали.

Более подробно эта проблема описана в статье Тони Уорда «Пришло время разрушить визуальное регрессионное тестирование «.

Мы изучили два возможных решения:

  1. Запуск Docker локально и в CI: это обеспечит использование одного базового образа в обеих средах. Однако, для нас это было неприменимо из-за лицензионных ограничений и высокого порога входа, которого такое решение привнесло бы.
  2. 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, получает упрощённый и быстрый доступ к отчету, просмотр визуальных различий и принятие решения об одобрении или отклонении изменений.

Скриншот сгенерированного комментария на Github, сообщающего о различиях в снапшотах

Действие 2: Обновление снапшотов в комментариях

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

Скриншот комментария на Github с телом /approve-snapshots

Код для второго 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.

Снимок экрана сгенерированного комментария на Github, сообщающего о запуске действия обновления моментального снимка

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.

Снимок экрана, показывающий, что изменения в снапшоте были зафиксированы и перенесены в текущий PR

7. Комментарий про успешный апдейт

- name: Comment success
  uses: thollander/actions-comment-pull-request@v3
  with:
    message: |
      ### 🎉 Successfully updated and committed Playwright snapshots! 🎉

Наконец, действие публикует комментарий об успехе в PR, сообщая команде, что снапшоты были успешно обновлены и закомичены.

Снимок экрана сгенерированного комментария на Github, сообщающего об успешной фиксации обновлений

Заключение

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

Этот новый подход не только помог нам повысить эффективность тестирования, но и дал уверенность в том, что наши визуальные тесты надежны и последовательны, независимо от того, кто их проводит и в какой среде они работают.

Для практической демонстрации этой настройки вы можете посмотреть это репо с запросом на выгрузку, в котором показан весь процесс, от запуска тестов Playwright до апрува обновлений снапшотов.

Огромная благодарность!

Я хочу выразить огромную благодарность двум инженерам из другой компании, Тони и Клинтону, за то, что они также столкнулись с этой проблемой со снапшотами в CI и вместе со мной разработали это решение. Это сотрудничество помогло нам выработать чистый и автоматизированный подход, и мы надеемся, что он поможет другим людям, которые могут столкнуться с такой же проблемой. ❤️

🔥 Какой была ваша первая зарплата в QA и как вы искали первую работу? 

Мега обсуждение в нашем телеграм-канале о поиске первой работы. Обмен опытом и мнения.

Читать в телеграм

Оставьте комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *