CI/CD для Playwright в GitHub Actions — это автоматический запуск автотестов на сервере GitHub при каждом пуше или пул-реквесте, а не только вручную на компьютере разработчика. Workflow-файл в формате YAML описывает, какую виртуальную машину поднять, какие браузеры установить и куда сохранить отчёт о прогоне — команда видит результат тестов прямо в интерфейсе GitHub, без необходимости гонять их локально перед каждым релизом.
Как выглядит минимальный workflow для Playwright в GitHub Actions?
# .github/workflows/playwright.yml
name: Playwright Tests
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
timeout-minutes: 60
runs-on: ubuntu-latest
steps:
name: Playwright Tests
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
timeout-minutes: 60
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: actions/setup-node@v7
- with:
- node-version: 24
- name: Install dependencies
- run: npm ci
- name: Install Playwright Browsers
- run: npx playwright install --with-deps
- name: Run Playwright tests
- run: npx playwright test
- uses: actions/upload-artifact@v7
- if: ${{ !cancelled() }}
- with:
- name: playwright-report
- path: playwright-report/
- retention-days: 30
Каждый step — отдельная команда на чистой виртуальной машине: actions/checkout скачивает код репозитория, setup-node ставит нужную версию Node.js, npm ci устанавливает зависимости строго по package-lock.json (в отличие от npm install, не изменяет lock-файл и работает быстрее в CI), а npx playwright install --with-deps ставит сами браузеры Playwright вместе с системными библиотеками Linux, без которых браузеры не запустятся на чистом образе Ubuntu. Финальный шаг actions/upload-artifact сохраняет HTML-отчёт как загружаемый файл в интерфейсе GitHub Actions — его можно скачать и открыть даже после того, как виртуальная машина CI уже удалена.
Зачем нужен --with-deps в команде установки браузеров?
Флаг --with-deps в npx playwright install --with-deps доустанавливает системные библиотеки Linux (шрифты, кодеки, графические зависимости), которые нужны браузерам Chromium/Firefox/WebKit для запуска — обычная команда npx playwright install ставит только сами браузеры, но не трогает системные пакеты через apt. На чистом образе ubuntu-latest без этих системных зависимостей браузер, скорее всего, упадёт с ошибкой запуска ещё до первого теста. На локальной машине разработчика этот флаг обычно не нужен, потому что нужные системные библиотеки уже стоят вместе с обычным десктопным окружением.
Как ускорить CI за счёт кэширования браузеров Playwright?
- name: Get installed Playwright version
- id: playwright-version
- run: echo "version=$(npm ls @playwright/test --json | jq -r '.dependencies["@playwright/test"].version')" >> $GITHUB_OUTPUT
- name: Cache Playwright browsers
- uses: actions/cache@v6
- id: playwright-cache
- with:
- path: ~/.cache/ms-playwright
- key: playwright-${{ steps.playwright-version.outputs.version }}
- name: Install Playwright Browsers
- if: steps.playwright-cache.outputs.cache-hit != 'true'
- run: npx playwright install --with-deps
- name: Install only system deps
- if: steps.playwright-cache.outputs.cache-hit == 'true'
- run: npx playwright install-deps
Загрузка браузеров Playwright занимает заметную часть времени каждого прогона CI, если скачивать их заново на каждой сборке. actions/cache сохраняет папку ~/.cache/ms-playwright (где Playwright хранит бинарники браузеров на Linux) между прогонами по ключу, который включает версию @playwright/test — при следующем запуске с той же версией браузеры возьмутся из кэша вместо повторного скачивания. Условие if: steps.playwright-cache.outputs.cache-hit != 'true' пропускает полную установку, если кэш уже найден, но install-deps всё равно нужно вызвать отдельно, потому что кэш сохраняет только бинарники браузеров, а не системные библиотеки Ubuntu.
Как разбить тесты на параллельные шарды (sharding) в GitHub Actions?
jobs:
test:
strategy:
fail-fast: false
matrix:
shardIndex: [1, 2, 3, 4]
shardTotal: [4]
steps:
test:
strategy:
fail-fast: false
matrix:
shardIndex: [1, 2, 3, 4]
shardTotal: [4]
steps:
- run: npx playwright test --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }} --reporter=blob
- uses: actions/upload-artifact@v7
- if: ${{ !cancelled() }}
- with:
- name: blob-report-${{ matrix.shardIndex }}
- path: blob-report
- retention-days: 1
strategy.matrix запускает job параллельно в нескольких экземплярах — по одному на каждое значение shardIndex, то есть в этом примере тесты выполнятся на 4 отдельных виртуальных машинах одновременно. Флаг --shard=N/M в самом Playwright делит общий набор тестовых файлов на M частей и запускает только часть с номером N — по умолчанию (если в конфиге не включён fullyParallel: true) деление происходит по количеству тестовых файлов, а не по времени их выполнения, поэтому для равномерной нагрузки желательно, чтобы файлы тестов были примерно сопоставимы по продолжительности; при включённом fullyParallel: true Playwright шардит уже на уровне отдельных тестов, а не файлов целиком. fail-fast: false не даёт GitHub Actions остановить все остальные шарды, если один из них упал — иначе по умолчанию вся матрица отменяется при первой же ошибке. Шаг actions/upload-artifact с именем blob-report-${{ matrix.shardIndex }} сохраняет blob-отчёт каждого шарда отдельно — именно эти артефакты дальше скачивает и склеивает job merge-reports ниже.
Как объединить отчёты с нескольких шардов в один?
merge-reports:
if: ${{ !cancelled() }}
needs: [test]
runs-on: ubuntu-latest
steps:
if: ${{ !cancelled() }}
needs: [test]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: actions/setup-node@v7
- with:
- node-version: 24
- run: npm ci
- uses: actions/download-artifact@v8
- with:
- path: all-blob-reports
- pattern: blob-report-*
- merge-multiple: true
- run: npx playwright merge-reports --reporter html ./all-blob-reports
- uses: actions/upload-artifact@v7
- with:
- name: html-report
- path: playwright-report
- retention-days: 30
Каждый шард по отдельности формирует свою часть общего прогона, и если не объединить их результаты, вместо одного отчёта получится N разрозненных. Job merge-reports с needs: [test] запускается только после завершения всех job из матрицы test, скачивает все промежуточные blob-отчёты (их нужно сохранить с шагом blob репортером в самой job test — npx playwright test --reporter=blob — отдельно от финального HTML) через actions/download-artifact и склеивает их командой npx playwright merge-reports в единый HTML-отчёт.
Какие GitHub Actions чаще всего используются в CI для Playwright?
В примерах выше повторяются пять готовых actions из официального набора GitHub — их не нужно писать самостоятельно, достаточно подключить через uses: в workflow-файле.
— `actions/checkout` (v7) — скачивает код репозитория на виртуальную машину. Без этого шага у workflow нет доступа к файлам проекта, включая тесты.
— `actions/setup-node` (v7) — устанавливает нужную версию Node.js (в примерах — 24, текущая активная LTS-версия), чтобы работали npm ci и команды Playwright.
— `actions/cache` (v6) — сохраняет и восстанавливает файлы между запусками workflow по ключу. В статье используется для кэширования браузеров Playwright в ~/.cache/ms-playwright.
— `actions/upload-artifact` (v7) — загружает файлы (HTML-отчёт, blob-отчёты по шардам) как артефакты, доступные для скачивания в интерфейсе GitHub Actions после завершения job.
— `actions/download-artifact` (v8) — скачивает артефакты, загруженные другой job. В примере выше нужен job merge-reports, чтобы получить blob-отчёты со всех шардов.
Версии экшенов и Node.js стоит периодически сверять с актуальными релизами самостоятельно — GitHub Actions регулярно выпускает новые major-версии, а старые в какой-то момент перестают поддерживаться раннерами (например, экшены на устаревшем рантайме Node.js рано или поздно требуют апгрейда вместе с переходом самих раннеров GitHub на новую версию Node).
— `actions/checkout` (v7) — скачивает код репозитория на виртуальную машину. Без этого шага у workflow нет доступа к файлам проекта, включая тесты.
— `actions/setup-node` (v7) — устанавливает нужную версию Node.js (в примерах — 24, текущая активная LTS-версия), чтобы работали npm ci и команды Playwright.
— `actions/cache` (v6) — сохраняет и восстанавливает файлы между запусками workflow по ключу. В статье используется для кэширования браузеров Playwright в ~/.cache/ms-playwright.
— `actions/upload-artifact` (v7) — загружает файлы (HTML-отчёт, blob-отчёты по шардам) как артефакты, доступные для скачивания в интерфейсе GitHub Actions после завершения job.
— `actions/download-artifact` (v8) — скачивает артефакты, загруженные другой job. В примере выше нужен job merge-reports, чтобы получить blob-отчёты со всех шардов.
Версии экшенов и Node.js стоит периодически сверять с актуальными релизами самостоятельно — GitHub Actions регулярно выпускает новые major-версии, а старые в какой-то момент перестают поддерживаться раннерами (например, экшены на устаревшем рантайме Node.js рано или поздно требуют апгрейда вместе с переходом самих раннеров GitHub на новую версию Node).
Как сохранить видео и трассировку упавших тестов в CI?
// playwright.config.ts
export default defineConfig({
use: {
trace: 'on-first-retry',
video: 'retain-on-failure',
screenshot: 'only-on-failure',
},
retries: process.env.CI ? 2 : 0,
});
export default defineConfig({
use: {
trace: 'on-first-retry',
video: 'retain-on-failure',
screenshot: 'only-on-failure',
},
retries: process.env.CI ? 2 : 0,
});
Записывать трассировку и видео для каждого теста подряд — избыточно и замедляет прогон, поэтому в конфиге принято включать их только при неудаче: trace: 'on-first-retry' запишет трассировку только при первой повторной попытке упавшего теста (не при первом же прогоне — если тест сразу нестабильный, это экономит место), video: 'retain-on-failure' записывает видео всегда, но сохраняет файл только для тестов, которые в итоге упали, screenshot: 'only-on-failure' делает скриншот в момент падения. process.env.CI — стандартная переменная окружения, которую GitHub Actions (и большинство CI-систем) автоматически выставляет в 'true' внутри job — по ней конфиг включает повторные попытки (retries: 2) только в CI, не мешая локальной отладке, где повторные попытки обычно только маскируют реальную нестабильность теста.
Какие шаги CI/CD-настройки Playwright стоит запомнить?
— `actions/checkout` + `actions/setup-node` — базовая подготовка окружения: код репозитория и нужная версия Node.js.
— `npm ci` — установка зависимостей строго по lock-файлу, быстрее и надёжнее npm install в CI.
— `npx playwright install --with-deps` — установка браузеров вместе с системными библиотеками Linux, обязательна на чистом образе.
— `actions/cache` на `~/.cache/ms-playwright` — кэширование браузеров между прогонами по ключу версии.
— `strategy.matrix` + `--shard=N/M` — параллельный прогон тестов на нескольких машинах одновременно.
— `npx playwright merge-reports` — склейка blob-отчётов с разных шардов в один HTML-отчёт.
— `trace: 'on-first-retry'`, `video: 'retain-on-failure'` — диагностика падений без раздувания отчёта на каждый успешный тест.
— `npm ci` — установка зависимостей строго по lock-файлу, быстрее и надёжнее npm install в CI.
— `npx playwright install --with-deps` — установка браузеров вместе с системными библиотеками Linux, обязательна на чистом образе.
— `actions/cache` на `~/.cache/ms-playwright` — кэширование браузеров между прогонами по ключу версии.
— `strategy.matrix` + `--shard=N/M` — параллельный прогон тестов на нескольких машинах одновременно.
— `npx playwright merge-reports` — склейка blob-отчётов с разных шардов в один HTML-отчёт.
— `trace: 'on-first-retry'`, `video: 'retain-on-failure'` — диагностика падений без раздувания отчёта на каждый успешный тест.
Какие вопросы про CI/CD Playwright в GitHub Actions задают чаще всего?
Обязательно ли использовать именно GitHub Actions, или подход применим к другим CI-системам? Сама логика (установка браузеров, кэширование, шардинг, сбор артефактов) применима к любой CI-системе — GitLab CI, CircleCI, Jenkins — меняется только синтаксис описания job (YAML-структура специфична для GitHub Actions), а команды Playwright (npx playwright test --shard, merge-reports) остаются теми же.
Нужно ли устанавливать все три браузера (Chromium, Firefox, WebKit) в CI, если проект использует только один? Нет, npx playwright install --with-deps без аргументов ставит все браузеры, но можно указать конкретный — npx playwright install --with-deps chromium — если playwright.config.ts использует только один браузер в projects, это ускоряет установку и не расходует лишнее место на диске CI-раннера.
Что делать, если тесты в CI падают, а локально проходят стабильно? Частые причины — различия в системных шрифтах и рендеринге между локальной ОС и Linux-образом CI (особенно для визуальных сравнений скриншотов), более ограниченные ресурсы CPU/памяти у CI-раннера (проявляется как таймауты в тестах, которые локально укладываются с запасом), и часто более быстрый или, наоборот, более медленный сетевой доступ до тестируемого окружения. Артефакты (trace, video, screenshot), сохранённые именно из CI-прогона, обычно быстрее всего показывают причину.
Можно ли запускать тесты только для изменённых файлов, а не всего набора? Playwright поддерживает --only-changed (сравнение с git-историей) для тестирования только затронутых изменениями файлов, но на практике для CI чаще применяют более грубое разделение: гонять полный набор на main/pull_request в push, а для больших монорепозиториев — ограничивать job через paths в триггере on.push/on.pull_request, чтобы workflow вообще не запускался, если изменения не коснулись директории с тестами или тестируемым кодом.
Как безопасно хранить в GitHub Actions секреты — API-ключи, тестовые логины и пароли, URL тестового окружения? Значения добавляются в Settings → Secrets and variables → Actions репозитория (или в конкретное Environment для более строгого доступа) и обращаются в workflow как ${{ secrets.MY_SECRET }} — GitHub автоматически маскирует такие значения в логах job, даже если тест случайно выведет их в консоль. Хранить пароли и ключи прямо в YAML-файле или в .env, закоммиченном в репозиторий, нельзя — файл виден всем, у кого есть доступ к коду. Для проде-подобных окружений можно завести Environment с обязательным подтверждением (required reviewers), чтобы job с реальными продовыми секретами не запускался автоматически без ручного одобрения.
Нужно ли устанавливать все три браузера (Chromium, Firefox, WebKit) в CI, если проект использует только один? Нет, npx playwright install --with-deps без аргументов ставит все браузеры, но можно указать конкретный — npx playwright install --with-deps chromium — если playwright.config.ts использует только один браузер в projects, это ускоряет установку и не расходует лишнее место на диске CI-раннера.
Что делать, если тесты в CI падают, а локально проходят стабильно? Частые причины — различия в системных шрифтах и рендеринге между локальной ОС и Linux-образом CI (особенно для визуальных сравнений скриншотов), более ограниченные ресурсы CPU/памяти у CI-раннера (проявляется как таймауты в тестах, которые локально укладываются с запасом), и часто более быстрый или, наоборот, более медленный сетевой доступ до тестируемого окружения. Артефакты (trace, video, screenshot), сохранённые именно из CI-прогона, обычно быстрее всего показывают причину.
Можно ли запускать тесты только для изменённых файлов, а не всего набора? Playwright поддерживает --only-changed (сравнение с git-историей) для тестирования только затронутых изменениями файлов, но на практике для CI чаще применяют более грубое разделение: гонять полный набор на main/pull_request в push, а для больших монорепозиториев — ограничивать job через paths в триггере on.push/on.pull_request, чтобы workflow вообще не запускался, если изменения не коснулись директории с тестами или тестируемым кодом.
Как безопасно хранить в GitHub Actions секреты — API-ключи, тестовые логины и пароли, URL тестового окружения? Значения добавляются в Settings → Secrets and variables → Actions репозитория (или в конкретное Environment для более строгого доступа) и обращаются в workflow как ${{ secrets.MY_SECRET }} — GitHub автоматически маскирует такие значения в логах job, даже если тест случайно выведет их в консоль. Хранить пароли и ключи прямо в YAML-файле или в .env, закоммиченном в репозиторий, нельзя — файл виден всем, у кого есть доступ к коду. Для проде-подобных окружений можно завести Environment с обязательным подтверждением (required reviewers), чтобы job с реальными продовыми секретами не запускался автоматически без ручного одобрения.
Как закрепить CI/CD для Playwright на практике?
Настроить workflow с кэшированием и шардингом на бумаге просто, а вот увидеть вживую, как объединяются blob-отчёты с четырёх параллельных job или почему тест падает именно в CI, а не локально, — куда полезнее на реальном проекте. В курсе Quality Academy «Автотестирование JS/TS + Playwright» есть отдельный собственный проект с настройкой CI, разбором домашних заданий у ментора и созвонами — 12 спринтов, 24 лекции, 4 месяца. А если пока хочется просто освоить основы Playwright — бесплатный тренажёр Playwright Arena: 30 задач в трёх модулях, без оплаты.
-------
Полезные ссылки школы
Сайт Quality Academy:
/main
Telegram-канал:
https://t.me/quality_academy
YouTube-канал:
https://www.youtube.com/@quality_academy
ВКонтакте:
https://vk.com/quality_academy
Канал отзывов учеников (58+ отзывов):
https://t.me/quality_academy_reviews
Задать вопрос менеджеру:
https://t.me/quality_academy_bot
Тест «Подойдёт ли вам тестирование»:
https://quiz.quality-academy.ru
5000+ вопросов с собесов тестировщика — бот-тренажёр:
https://t.me/quality_academy_interview_bot
3 практические задачи и дорожная карта:
https://t.me/quality_academy_tasks_bot
Бесплатные тренажёры — SQL Arena, Playwright Arena, Python Arena:
SQL Arena · Playwright Arena · Python Arena
/main
Telegram-канал:
https://t.me/quality_academy
YouTube-канал:
https://www.youtube.com/@quality_academy
ВКонтакте:
https://vk.com/quality_academy
Канал отзывов учеников (58+ отзывов):
https://t.me/quality_academy_reviews
Задать вопрос менеджеру:
https://t.me/quality_academy_bot
Тест «Подойдёт ли вам тестирование»:
https://quiz.quality-academy.ru
5000+ вопросов с собесов тестировщика — бот-тренажёр:
https://t.me/quality_academy_interview_bot
3 практические задачи и дорожная карта:
https://t.me/quality_academy_tasks_bot
Бесплатные тренажёры — SQL Arena, Playwright Arena, Python Arena:
SQL Arena · Playwright Arena · Python Arena