Настройка визуального регрессионного тестирования 1С-Битрикс
Обновление CSS в шаблоне, изменение компонента, обновление jQuery — и кнопка «Купить» съезжает на 3 пикселя, блок с ценой перекрывает галерею на мобильных, шрифт карточки товара стал на 2px меньше. Глазами не поймать. Визуальное регрессионное тестирование делает скриншот страницы до и после изменений и сравнивает попиксельно.
Инструменты
Playwright + встроенный snapshot-тест — наиболее интегрированный вариант, если Playwright уже используется для E2E. Хранит эталонные скриншоты в репозитории, сравнивает при каждом запуске.
Percy (BrowserStack) — SaaS-сервис с визуальным дашбордом, удобной ревью-системой, поддержкой адаптива. Требует платной подписки при объёме > 5 000 снимков/месяц.
Chromatic — аналог Percy, заточен под Storybook. Если у проекта есть библиотека компонентов — хороший выбор.
Для большинства Битрикс-проектов Playwright со встроенными snapshot-тестами — достаточно.
Настройка snapshot-тестов в Playwright
// playwright.config.ts
import { defineConfig } from '@playwright/test';
export default defineConfig({
snapshotPathTemplate: '{testDir}/__snapshots__/{testFilePath}/{arg}{ext}',
expect: {
toHaveScreenshot: {
maxDiffPixels: 50, // допуск: 50 пикселей разницы
threshold: 0.01, // 1% различий на пиксель
animations: 'disabled', // отключаем CSS-анимации
},
},
});
Базовые visual-тесты для Битрикс
// tests/visual/catalog.spec.ts
import { test, expect } from '@playwright/test';
test.describe('Catalog visual', () => {
test('catalog section page', async ({ page }) => {
await page.goto('/catalog/electronics/');
// Ждём загрузки изображений
await page.waitForLoadState('networkidle');
// Скрываем динамические элементы (цены со скидкой по времени, счётчики)
await page.evaluate(() => {
document.querySelectorAll('.catalog-item-label-sale').forEach(el => {
(el as HTMLElement).style.visibility = 'hidden';
});
});
await expect(page).toHaveScreenshot('catalog-section.png');
});
test('product card', async ({ page }) => {
await page.goto('/catalog/electronics/headphones/model-x100/');
await page.waitForLoadState('networkidle');
// Скрываем таймер акции если есть
await page.evaluate(() => {
const timer = document.querySelector('.sale-timer');
if (timer) (timer as HTMLElement).style.display = 'none';
});
await expect(page).toHaveScreenshot('product-card.png', { fullPage: false });
});
test('cart page', async ({ page }) => {
// Логинимся и добавляем товар
await page.request.post('/local/ajax/cart-add.php', {
data: { product_id: 123, quantity: 1 }
});
await page.goto('/personal/cart/');
await page.waitForLoadState('networkidle');
await expect(page).toHaveScreenshot('cart.png');
});
});
Мобильный viewport
Отдельный проект в конфиге для мобильного вида:
// playwright.config.ts
projects: [
{
name: 'desktop-chrome',
use: { viewport: { width: 1440, height: 900 } },
},
{
name: 'mobile-iphone',
use: {
...devices['iPhone 14'],
viewport: { width: 390, height: 844 },
},
testMatch: '**/visual/**',
},
],
Обновление эталонных скриншотов
При намеренном изменении дизайна эталоны обновляются командой:
npx playwright test --update-snapshots tests/visual/
Обновлённые скриншоты коммитятся в репозиторий как часть PR. Ревьюер видит в diff'е не только код, но и визуальные изменения.
Маскирование динамических элементов
Битрикс-страницы содержат элементы, которые меняются каждый раз: счётчики посетителей, таймеры акций, «Сегодня просматривают» и подобное. Их нужно маскировать:
await expect(page).toHaveScreenshot('homepage.png', {
mask: [
page.locator('.bx-visitor-counter'),
page.locator('.product-views-count'),
page.locator('.sale-countdown-timer'),
page.locator('.personal-greeting'), // «Добрый день, Иван»
],
});
CI/CD интеграция
# .github/workflows/visual.yml
visual-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: npx playwright install chromium
- run: npx playwright test tests/visual/
env:
TEST_BASE_URL: ${{ secrets.STAGING_URL }}
- uses: actions/upload-artifact@v4
if: failure()
with:
name: visual-diff
path: test-results/
При падении теста в test-results/ будут три файла: эталон, актуальный снимок и diff с подсвеченными различиями.
Стратегия внедрения
| Этап | Что делать | Срок |
|---|---|---|
| Базовые снимки | 10-15 ключевых страниц в десктопе и мобайле | 1–2 дня |
| CI-интеграция | Запуск при PR на staging | 0.5 дня |
| Расширение покрытия | Компоненты каталога, корзина, чекаут | 2–3 дня |
| Мобильный профиль | Отдельные тесты для 375px, 768px | 1 день |
Начинайте с главной, страницы каталога, карточки товара и корзины — это 80% того, что ломается при обновлениях шаблона.







