automationplaywright

Headless vs headed браузер в CI: что выбрать

Headless браузер (без GUI) экономит ресурсы. Headed (с GUI) помогает отлаживать и видеть что происходит. Большинство CI-пайплайнов работают в headless — но есть кейсы где это создаёт проблемы.

Различия на практике

Headless — браузер рендерит страницу, но не показывает её на экране. Внутри Chrome/Firefox это специальный режим.

Headed — обычный браузер с UI. Можно открыть в --headed режиме Playwright или Selenium, увидеть как тесты тапают по элементам.

Что меняется в поведении

Заявленная цель headless — идентичное поведение с headed. На практике есть мелкие различия:

navigator.webdriver возвращает true в headless по умолчанию (антибот-системы могут это видеть). — User-Agent: некоторые серверы детектят headless по UA-строке (HeadlessChrome в старых версиях). — Viewport: по умолчанию headless запускается с фиксированным viewport, headed может зависеть от размера окна. — WebGL / Canvas: некоторые GPU-операции в headless могут отличаться. — Fonts: на CI-серверах могут отсутствовать системные шрифты (особенно эмодзи, кириллица) → текст рендерится fallback’ом.

Когда headless подходит

Большая часть тестов — функциональные, accessibility, smoke. В CI быстрее, экономит RAM/CPU.

Headless параллелится лучше — 10 параллельных воркеров без GPU-конкуренции.

Docker-friendly — не нужен X-сервер.

Когда нужен headed (или режим близкий к нему)

⚠️ Visual regression: разница в рендере между headed и headless может вызывать false positives. Делай baselines в том же режиме что и тестовые runs.

⚠️ Антибот-системы (Cloudflare Turnstile, reCAPTCHA): они часто блокируют headless. Если тестируешь сайт защищённый антиботом — используй headed + flag --disable-blink-features=AutomationControlled.

⚠️ WebGL/Three.js приложения: на CI без GPU headless рендерит через SwiftShader (программный), скорость и качество отличаются.

⚠️ Аудио/видео: некоторые медиа-API могут вести себя по-разному без аудиоустройства в системе.

⚠️ Отладка локально: при разработке нового теста лучше headed — видишь что тестируется.

Конфигурация в Playwright

// playwright.config.ts
export default defineConfig({
  projects: [
    {
      name: 'chromium',
      use: {
        ...devices['Desktop Chrome'],
        headless: !!process.env.CI,  // headless в CI, headed локально
      }
    }
  ]
});

Также для visual-тестов лучше всегда headed:

{
  name: 'visual',
  use: { headless: false },
  testMatch: '**/*.visual.spec.ts'
}

Шрифты на CI

Самая частая проблема при переходе на CI — разные шрифты. На Ubuntu в Docker нет MS Arial → тесты рендерят fallback → пиксели не сходятся.

Решение для Playwright:

FROM mcr.microsoft.com/playwright:v1.40.0-jammy
# или
RUN apt-get install -y fonts-noto fonts-noto-cjk fonts-noto-color-emoji

Используй официальный Playwright Docker image — там предустановлены шрифты.

Что делать

✅ В CI — headless по умолчанию. Локально — headed для отладки.

✅ Для visual regression — единый режим (либо везде headless, либо везде headed).

✅ Если приложение защищено антиботом — рассмотри Playwright stealth plugin или headed-режим.

✅ Используй официальный Playwright Docker image — он решает 90% шрифт-проблем.

Подробнее: Playwright Browsers, Chrome headless mode.