Что различается между браузерами
Updated Jul 2026
Фокусируйте тестирование там, где браузеры действительно различаются
Не всё нуждается в кроссбраузерном тестировании. Современные веб-стандарты хорошо реализованы в основных браузерах для большинства функций. Ключ — знать, в каких областях существует значительная вариативность между браузерами, и сосредоточить усилия по тестированию именно там.
Оценка рисков по функциональным областям
| Область | Кроссбраузерный риск | Приоритет тестирования | Примечания |
|---|---|---|---|
| CSS Grid / Flexbox | Низкий (хорошо стандартизировано) | Уровень 2 | Согласованно во всех современных браузерах |
CSS has(), container queries |
Средний (новые функции) | Уровень 1 | Safari отставал в некоторых функциях |
| JavaScript core | Очень низкий | Уровень 3 | ES2020+ универсален в современных браузерах |
| Web API (WebRTC, WebGL и т.д.) | Высокий (реализация различается) | Уровень 1 | Каждый браузер реализует по-разному |
Элементы форм (<input type="date">) |
Высокий (сильно различаются) | Уровень 1 | Нативные date picker различаются кардинально |
| Рендеринг шрифтов | Средний (визуальные различия) | Визуальная регрессия | Субпиксельный рендеринг различается по ОС/браузеру |
| Поведение прокрутки | Средний (инерция, overscroll) | Уровень 2 | Инерционная прокрутка iOS уникальна |
| Touch vs mouse события | Высокий | Уровень 1 на мобильных | Порядок и тайминг событий различаются |
| Clipboard API | Высокий (различаются разрешения) | Уровень 1 | Safari требует пользовательский жест, Chrome — нет |
| Загрузка файлов / drag-and-drop | Средний | Уровень 2 | Поведение drop zone различается |
| Стили печати | Низкий (редко тестируется) | Ручная выборочная проверка | Пагинация различается по браузерам |
| CSS-анимации / переходы | Низкий | Уровень 3 | Производительность различается, визуальный результат согласован |
| Воспроизведение медиа (видео/аудио) | Высокий | Уровень 1 | Поддержка кодеков, политики автовоспроизведения различаются |
| WebSocket / SSE | Низкий | Уровень 3 | Хорошо стандартизировано |
| IndexedDB / localStorage | Низкий | Уровень 3 | Лимиты хранения различаются, но API согласован |
Области высокого риска подробно
Элементы форм
Нативные элементы форм — наиболее несогласованная область между браузерами. Элемент <input type="date"> отображает совершенно разные date picker в Chrome, Safari и Firefox:
test('date picker works across browsers', async ({ page, browserName }) => {
await page.goto('/booking');
const dateInput = page.locator('input[type="date"]');
// Different approaches needed per browser
if (browserName === 'chromium') {
// Chrome: can type directly in YYYY-MM-DD format
await dateInput.fill('2026-03-15');
} else if (browserName === 'webkit') {
// Safari: may need to interact with native picker
await dateInput.click();
await dateInput.type('03/15/2026');
} else if (browserName === 'firefox') {
// Firefox: supports direct input
await dateInput.fill('2026-03-15');
}
// Verify the value regardless of input method
await expect(dateInput).toHaveValue('2026-03-15');
});
Лучшая практика: используйте кастомный компонент date picker (например, react-datepicker) для согласованного кроссбраузерного поведения. Если вы используете нативные date input, тестируйте их во всех браузерах Уровня 1.
Web API
test('clipboard API works across browsers', async ({ page, browserName }) => {
await page.goto('/share');
// Grant clipboard permission
if (browserName === 'chromium') {
await page.context().grantPermissions(['clipboard-read', 'clipboard-write']);
}
// Click copy button
await page.click('[data-testid="copy-link-btn"]');
// Verify clipboard content
// Note: Safari requires user gesture for clipboard access
const clipboardText = await page.evaluate(async () => {
return navigator.clipboard.readText();
});
expect(clipboardText).toContain('example.com/share/');
});
Прокрутка и тач-события
test('infinite scroll loads more items', async ({ page, browserName }) => {
await page.goto('/products');
const initialCount = await page.locator('.product-card').count();
// Scroll to bottom -- behavior differs between browsers
await page.evaluate(() => {
window.scrollTo({
top: document.body.scrollHeight,
behavior: 'smooth'
});
});
// Wait for new items to load
await page.waitForTimeout(1000);
const newCount = await page.locator('.product-card').count();
expect(newCount).toBeGreaterThan(initialCount);
});
Тестирование поддержки CSS-функций
Используйте запросы @supports для определения возможностей браузера, но также тестируйте поведение фоллбека:
test('CSS container queries have fallback', async ({ page }) => {
await page.goto('/dashboard');
// Check if the browser supports container queries
const supportsContainerQueries = await page.evaluate(() => {
return CSS.supports('container-type', 'inline-size');
});
if (supportsContainerQueries) {
// Verify responsive card layout
const card = page.locator('.dashboard-card').first();
const box = await card.boundingBox();
expect(box?.width).toBeGreaterThan(0);
} else {
// Verify fallback layout works
const card = page.locator('.dashboard-card').first();
const box = await card.boundingBox();
expect(box?.width).toBeGreaterThan(0);
// Fallback should still be usable
}
});
Советы по отладке для конкретных браузеров
| Браузер | Функция DevTools | Применение в тестировании |
|---|---|---|
| Chrome | Rendering tab > Paint flashing | Выявление проблем перерисовки |
| Chrome | Network > Throttling | Симуляция медленных соединений |
| Safari | Web Inspector > Layers | Отладка проблем композитинга |
| Safari | Responsive Design Mode | Симуляция iOS-устройств |
| Firefox | Accessibility Inspector | Проверка ARIA-дерева |
| Firefox | CSS Grid Inspector | Отладка проблем grid-вёрстки |
| Edge | Application > Service Workers | Отладка проблем PWA |
Автоматическое обнаружение кроссбраузерных различий
// tests/cross-browser/visual-diff.spec.ts
import { test, expect } from '@playwright/test';
test.describe('Cross-Browser Visual Consistency', () => {
const criticalPages = ['/', '/products', '/checkout'];
for (const pagePath of criticalPages) {
test(`${pagePath} looks consistent across browsers`, async ({ page }) => {
await page.goto(pagePath);
await page.waitForLoadState('networkidle');
// Take a screenshot -- Playwright compares across browser projects
await expect(page).toHaveScreenshot(`${pagePath.replace(/\//g, '-')}.png`, {
maxDiffPixelRatio: 0.05, // 5% tolerance for browser differences
threshold: 0.3, // Allow font rendering differences
animations: 'disabled',
});
});
}
});
Ключевой вывод: не тестируйте всё везде. Сосредоточьте кроссбраузерное тестирование на конкретных областях, где браузеры расходятся — элементы форм, Web API, работа с медиа и тач-взаимодействия. Для хорошо стандартизированных функций, таких как Flexbox, JavaScript и базовый CSS, достаточно тестирования на уровне движков (Blink, WebKit, Gecko).