Налаштування візуального регресійного тестування 1С-Бітрікс
Оновлення CSS у шаблоні, зміна компонента, оновлення jQuery — і кнопка «Купити» зміщується на 3 пікселі, блок із ціною перекриває галерею на мобільних, шрифт картки товару став на 2px менший. Очима не вловиш. Візуальне регресійне тестування робить скриншот сторінки до та після змін і порівнює попіксельно.
Інструменти
Playwright + вбудований snapshot-тест — найбільш інтегрований варіант, якщо Playwright вже використовується для E2E. Зберігає еталонні скриншоти в репозиторії, порівнює при кожному запуску.
Percy (BrowserStack) — SaaS-сервіс з візуальним дашбордом, зручною системою рев'ю, підтримкою адаптиву. Потребує платної підписки при обсязі > 5 000 знімків/місяць.
Chromatic — аналог Percy, заточений під Storybook. Якщо у проєкту є бібліотека компонентів — хороший вибір.
Для більшості проєктів на 1С-Бітрікс 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-тести для 1С-Бітрікс
// 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'і не тільки код, а й візуальні зміни.
Маскування динамічних елементів
Сторінки 1С-Бітрікс містять елементи, які змінюються щоразу: лічильники відвідувачів, таймери акцій, «Сьогодні переглядають» та подібне. Їх потрібно маскувати:
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% того, що ламається при оновленнях шаблону.







