Safari занимает 27% мобильного веб-трафика, и каждый iOS-браузер включая Chrome на iPhone работает на WebKit под капотом: пропустить WebKit значит пропустить всех iPhone-пользователей. Chrome и Edge используют один движок Chromium, поэтому вместе покрывают около 78% десктопного трафика одним браузерным проектом. Здесь разобрано как распределить покрытие браузеров по уровню риска для пользователей, настроить проекты Playwright для каждого движка, и не дать кросс-браузерному CI утроить время выполнения.

Почему браузеры всё ещё отличаются

Современные браузеры (Chrome, Firefox, Safari, Edge) поддерживают одни и те же стандарты HTML, CSS и JavaScript. Но различия остаются.

CSS-рендеринг. Flexbox-отступы, поведение grid, рендеринг шрифтов, shadow DOM: браузеры реализуют спецификации немного по-разному. JavaScript API. Некоторые новые API не поддерживаются в старых версиях Safari. Array.at(), structuredClone(), ResizeObserver: у всех разный уровень поддержки. Элементы форм. Выбор даты, инпуты файлов, select-элементы: браузеры стилизуют и обрабатывают их по-разному. Рендеринг PDF. Safari обрабатывает PDF иначе чем Chrome. WebKit на iOS. iOS использует WebKit для всех браузеров. Chrome на iPhone работает на WebKit под капотом. Safari на Mac и Safari на iPhone используют один движок.

Доля рынка браузеров (2025)

| Браузер | Десктоп | Мобильный |

|---------|---------|-----------|

| Chrome | ~65% | ~66% |

| Safari | ~12% | ~27% |

| Firefox | ~3% | ~1% |

| Edge | ~13% | ~3% |

Safari критичен для мобильного трафика. Edge основан на Chromium. Firefox занимает малую долю рынка, но важен для enterprise и отдельных регионов.

Практическая стратегия

Протестировать всё во всех браузерах невозможно. Практическая иерархия:

Уровень 1: тестировать всегда (каждый спринт)

Chrome занимает наибольшую долю рынка и является основным браузером разработки. Safari критичен для iOS/macOS-пользователей.

Уровень 2: тестировать перед крупными релизами

Firefox занимает меньшую долю рынка, но отличается качеством рендеринга. Edge основан на Chromium и несёт низкий дополнительный риск.

Уровень 3: тестировать для конкретных фич

Safari iOS при тестировании мобильных флоу, Chrome Android для поведений специфичных для мобильных, и конкретные версии браузера когда этого требуют enterprise-клиенты.

Настройка кросс-браузерного тестирования в Playwright

Playwright поддерживает Chrome, Firefox и WebKit (движок Safari) из коробки:

// playwright.config.ts
import { defineConfig, devices } from '@playwright/test';

export default defineConfig({
  projects: [
    // Десктопные браузеры
    {
      name: 'chromium',
      use: { ...devices['Desktop Chrome'] },
    },
    {
      name: 'firefox',
      use: { ...devices['Desktop Firefox'] },
    },
    {
      name: 'webkit',
      use: { ...devices['Desktop Safari'] },
    },
    
    // Мобильные браузеры
    {
      name: 'mobile-chrome',
      use: { ...devices['Pixel 7'] },
    },
    {
      name: 'mobile-safari',
      use: { ...devices['iPhone 14'] },
    },
  ],
});

Запуск конкретного браузера:

npx playwright test --project=webkit

Запуск всех браузеров:

npx playwright test

Что тестировать кросс-браузерно, а что нет

Тестировать кросс-браузерно

  • Основные пользовательские флоу (вход, оплата, ключевые сценарии)
  • Формы: особенно выбор даты, загрузку файлов, select
  • CSS-верстку: особенно дизайны с активным использованием flex/grid
  • JavaScript-зависимые фичи (сложные взаимодействия)
  • Мобильные флоу (тач, viewport, ориентация)

Не нужно тестировать кросс-браузерно

  • Юнит-тесты: независимы от браузера
  • API-тесты: браузер не задействован
  • Тесты бэкенд-логики
  • Внутренние административные инструменты которые использует только команда

Обработка браузер-специфичных падений

Когда тест падает только в одном браузере:

test('file upload', async ({ page, browserName }) => {
  // Пропускаем в WebKit: поведение file input значительно отличается
  test.skip(browserName === 'webkit', 'WebKit handles file inputs differently');
  
  await page.goto('/upload');
  await page.setInputFiles('[data-testid="file-input"]', 'test-file.pdf');
  await expect(page.getByTestId('upload-success')).toBeVisible();
});

Когда нужно браузер-специфичное поведение:

test('date picker works', async ({ page, browserName }) => {
  await page.goto('/book-appointment');
  
  if (browserName === 'webkit') {
    // Выбор даты в Safari требует другого взаимодействия
    await page.fill('[data-testid="date-input"]', '2026-06-15');
  } else {
    await page.click('[data-testid="date-input"]');
    await page.click('[data-date="2026-06-15"]');
  }
  
  await expect(page.getByTestId('selected-date')).toContainText('June 15');
});

BrowserStack и Sauce Labs

Встроенные браузеры Playwright используют open-source версии. Для тестирования на реальном Chrome (не Chromium), реальном Safari, и конкретных версиях браузеров используй облачные сервисы тестирования.

BrowserStack

// playwright.config.ts для BrowserStack
const capabilities = {
  'browserstack.user': process.env.BROWSERSTACK_USERNAME,
  'browserstack.key': process.env.BROWSERSTACK_ACCESS_KEY,
};

export default defineConfig({
  projects: [
    {
      name: 'chrome@latest-mac',
      use: {
        connectOptions: {
          wsEndpoint: `wss://cdp.browserstack.com/playwright?caps=${encodeURIComponent(JSON.stringify({
            ...capabilities,
            browserName: 'chrome',
            browserVersion: 'latest',
            'bstack:options': {
              os: 'OS X',
              osVersion: 'Sonoma',
            }
          }))}`,
        },
      },
    },
  ],
});

Когда облачные сервисы оправданы

  • Нужен реальный Safari (не WebKit) на реальном macOS
  • Конкретная версия Chrome (enterprise-клиенты зафиксированы на Chrome 110)
  • Тестирование на реальном iOS-устройстве (не симуляторе)
  • Поддержка IE11 (редко, но встречается в финансовом и государственном секторе)

Адаптивное тестирование

Тестируй при нескольких размерах viewport, а не только мобильный vs десктоп:

// playwright.config.ts
projects: [
  {
    name: 'desktop',
    use: { viewport: { width: 1920, height: 1080 } },
  },
  {
    name: 'laptop',
    use: { viewport: { width: 1280, height: 720 } },
  },
  {
    name: 'tablet',
    use: { viewport: { width: 768, height: 1024 } },
  },
  {
    name: 'mobile',
    use: { viewport: { width: 375, height: 667 } },  // iPhone SE
  },
],

Внутри теста:

test('navigation works on mobile', async ({ page }) => {
  await page.setViewportSize({ width: 375, height: 667 });
  await page.goto('/');
  
  // На мобильном: бургер-меню вместо навбара
  await expect(page.getByTestId('hamburger-menu')).toBeVisible();
  await expect(page.getByTestId('desktop-nav')).not.toBeVisible();
  
  await page.getByTestId('hamburger-menu').click();
  await expect(page.getByTestId('mobile-nav')).toBeVisible();
});

Управление кросс-браузерными падениями в CI

Запускай браузеры параллельно чтобы не замедлять CI:

# Матричная стратегия GitHub Actions
strategy:
  matrix:
    browser: [chromium, firefox, webkit]

steps:
  - run: npx playwright test --project=${{ matrix.browser }}

Или шардируй кросс-браузерные тесты:

strategy:
  matrix:
    include:
      - browser: chromium
        shard: 1/2
      - browser: chromium  
        shard: 2/2
      - browser: firefox
        shard: 1/1
      - browser: webkit
        shard: 1/1

Визуальное кросс-браузерное тестирование

Различия в CSS-рендеринге часто едва заметны. Сравнивать вручную утомительно. Используй Percy или встроенное сравнение скриншотов Playwright:

test('homepage renders correctly', async ({ page }) => {
  await page.goto('/');
  await expect(page).toHaveScreenshot('homepage.png', {
    maxDiffPixelRatio: 0.02,  // Допустимо 2% пиксельного отличия
  });
});

Скриншоты хранятся отдельно для каждого проекта: у каждого браузера своя базовая линия.

Практическая стратегия кросс-браузерного тестирования

1. Запускай полный сьют в Chrome на каждый коммит

2. Запускай Chrome и Safari перед каждым релизом

3. Запускай все браузеры (включая Firefox, Edge) перед крупными релизами

4. Тестируй мобильные viewport для адаптивных фич

Playwright упрощает кросс-браузерное тестирование: определяй проекты для каждого браузера, используй browserName для браузер-специфичного кода, test.skip() для известных несовместимостей, встроенный WebKit даёт Safari без macOS.

Цель не в том чтобы тестировать всё во всех браузерах. Цель: поймать браузер-специфичные баги которые реально затрагивают пользователей, используя имеющееся время.

→ See also: Кросс-браузерное тестирование с Playwright: Chrome, Firefox, Safari | Мобильная эмуляция в Playwright: тестирование адаптивности и сенсорного ввода | Параллельное выполнение в Playwright: workers, шарды и шардирование для ускорения