Эмуляция устройств в Playwright задаёт вьюпорт, pixel ratio, user agent и touch-события вместе, но не тестирует реальные мобильные движки: под капотом всё равно Chromium, независимо от того выбрал ли ты devices['iPhone 14']. Быстрый метод setViewportSize меняет только вьюпорт, но не user agent и не поведение тача, что достаточно для проверки адаптивной вёрстки, но неверно для всего что проверяет мобильный CSS или user-agent sniffing. Эта статья разбирает пресеты устройств, эмуляцию для отдельных тестов, разницу между setViewportSize и полной эмуляцией через newContext, touch-события, скриншот-регрессию для мобильных и сценарии когда нужен отдельный мобильный проект.
Что делает мобильная эмуляция (и чего не делает)
Эмуляция Playwright симулирует:
- Размеры вьюпорта
- Device pixel ratio (retina-экраны)
- Строку user agent
- Touch-события (вместо событий мыши)
- Геолокацию (опционально)
- Локаль и часовой пояс (опционально)
Что она не тестирует:
- Реальную производительность устройства
- Настоящие мобильные браузерные движки (по-прежнему Chromium, Firefox или WebKit)
- Рендеринг специфичный для железа
- Нативные мобильные приложения
Для тестирования на реальных устройствах нужны сервисы вроде BrowserStack или Sauce Labs. Эмуляция покрывает самую частую потребность: убедиться что приложение корректно работает при мобильных размерах вьюпорта и реагирует на тач.
Встроенные пресеты устройств
Playwright включает библиотеку пресетов устройств. Используй их в конфиге:
// playwright.config.ts
import { defineConfig, devices } from '@playwright/test';
export default defineConfig({
projects: [
{
name: 'chromium-desktop',
use: { ...devices['Desktop Chrome'] },
},
{
name: 'mobile-chrome',
use: { ...devices['Pixel 7'] },
},
{
name: 'mobile-safari',
use: { ...devices['iPhone 14'] },
},
{
name: 'tablet',
use: { ...devices['iPad Pro 11'] },
},
],
});Запуск только мобильных тестов:
npx playwright test --project=mobile-chromeВсе доступные устройства:
npx playwright --list-devicesСписок включает около 80 пресетов: устройства Pixel, iPhone, Galaxy, iPad, Surface.
Эмуляция устройства для отдельного теста
Переопределить эмуляцию для конкретного теста без изменения конфига:
import { test, expect, devices } from '@playwright/test';
test('mobile navigation works', async ({ browser }) => {
const context = await browser.newContext({
...devices['iPhone 14'],
});
const page = await context.newPage();
await page.goto('/');
// Кнопка-гамбургер должна быть видима на мобильном
await expect(page.getByRole('button', { name: 'Menu' })).toBeVisible();
await page.getByRole('button', { name: 'Menu' }).click();
await expect(page.getByRole('navigation')).toBeVisible();
await context.close();
});Touch-события
На мобильных устройствах Playwright использует touch-события вместо событий мыши. Большинство взаимодействий работают одинаково: click(), fill(), type() корректно транслируются. Там где тач важен:
// Тап (аналог клика на мобильном)
await page.getByRole('button').tap();
// Жест свайпа
await page.touchscreen.tap(100, 200);
// Перетаскивание на тачскрине
await page.touchscreen.tap(100, 400);
// затем симулируй свайп через серию точекДля свайп-каруселей, pull-to-refresh и сложных жестов может понадобиться page.evaluate() для генерации кастомных touch-событий. Большинство простых мобильных взаимодействий работают через обычные методы локаторов.
Тестирование адаптивного поведения
Самое практичное применение: проверить вёрстку на разных брейкпоинтах.
test.describe('responsive layout', () => {
test('desktop shows full nav', async ({ page }) => {
await page.setViewportSize({ width: 1280, height: 720 });
await page.goto('/');
await expect(page.getByRole('navigation')).toBeVisible();
await expect(page.getByRole('button', { name: 'Menu' })).not.toBeVisible();
});
test('mobile shows hamburger', async ({ page }) => {
await page.setViewportSize({ width: 375, height: 812 });
await page.goto('/');
await expect(page.getByRole('button', { name: 'Menu' })).toBeVisible();
await expect(page.getByRole('navigation')).not.toBeVisible();
});
});setViewportSize меняет только вьюпорт и не меняет user agent. Для полной эмуляции устройства используй пресеты devices или контекст с viewport, userAgent и deviceScaleFactor заданными вместе.
Только вьюпорт vs. полная конфигурация
// Только вьюпорт — не меняет user agent и touch-события
await page.setViewportSize({ width: 375, height: 812 });
// Полная эмуляция — вьюпорт + user agent + тач + pixel ratio
const context = await browser.newContext({
viewport: { width: 390, height: 844 },
userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X)...',
deviceScaleFactor: 3,
isMobile: true,
hasTouch: true,
});Для адаптивных тестов которые проверяют только вёрстку, setViewportSize достаточно. Для тестов которые проверяют мобильное поведение (touch-события, мобильный CSS, user-agent sniffing) используй полную эмуляцию через пресеты devices.
Скриншот-сравнение для адаптивного тестирования
Визуальная регрессия особенно ценна для мобильных: баги вёрстки часто невидимы в обычных ассёртах, но очевидны на скриншоте.
test('mobile homepage matches baseline', async ({ page }) => {
await page.setViewportSize({ width: 375, height: 812 });
await page.goto('/');
await expect(page).toHaveScreenshot('mobile-homepage.png', {
fullPage: true,
});
});Запусти один раз чтобы сгенерировать базовый скриншот. Последующие запуски сравнивают с ним. Сдвиг вёрстки даже на один пиксель провалит тест.
Что тестировать на мобильном
Не каждый тест нуждается в мобильной версии. Приоритет для:
- Навигации (кнопки-гамбургеры, мобильные драверы)
- Форм (виртуальная клавиатура не перекрывает кнопку отправки, тач-цели достаточно крупные)
- Таблиц (горизонтальный скролл vs. вертикальное расположение)
- Изображений (адаптивный
srcset, нет overflow) - Платёжных флоу (критический путь, кнопки удобные для тача)
- Модалов (контент прокручивается, кнопка закрытия доступна)
Пропускать мобильные тесты для административных панелей которые явно не поддерживают мобильный, для тестов проверяющих одинаковое поведение независимо от вьюпорта, а также для API-тестов и юнит-тестов.
→ See also: Кросс-браузерное тестирование с Playwright: Chrome, Firefox, Safari | Стратегии кросс-браузерного тестирования: когда и как тестировать в разных браузерах | Файл конфигурации Playwright: все опции, которые нужно знать