תארו לעצמכם: אתם מעדכנים תבנית CSS, משנים רכיב, או פשוט מוסיפים תוסף jQuery חדש. כפתור "קנייה" זז ב-3 פיקסלים, בלוק המחיר חופף לגלריה במובייל, והגופן בכרטיס המוצר קטן ב-2px. קשה לזהות ויזואלית, אבל לקוחות מתלוננים על פריסה שבורה. בדיקת רגרסיה ויזואלית (VRT) פותרת את זה: היא מצלמת מסך של הדף לפני ואחרי השינויים, משווה פיקסל-אחר-פיקסל, ומדגישה את ההבדלים. אנו מיישמים בדיקה זו בפרויקטים של Bitrix וחולקים את הניסיון שלנו. במשך שנים רבות סיפקנו יותר מ-150 פרויקטים, ובכל אחד מהם נתקלנו ברגרסיות ויזואליות לאחר עדכונים. בדיקות אוטומציה הן הדרך היחידה להבטיח יציבות פריסה ללא בדיקה ידנית של כל דף.
בדיקת רגרסיה ויזואלית היא נוהג סטנדרטי להבטחת עקביות ממשק משתמש, כפי שמצוין בתיעוד Playwright.
למה VRT חיונית לפרויקטים של 1C-Bitrix
אתרי 1C-Bitrix כוללים תבניות מורכבות עם התאמות אישיות, רכיבים ותוכן דינמי. אפילו שינוי עיצובי קטן יכול לשבור את הרספונסיביות, לחפוף אלמנטים, או לפגוע בתצוגה במובייל. בדיקה ידנית של כל דף לאחר כל פריסה היא יקרה ואיטית. אוטומציה פותרת את זה: צילומי מסך נלכדים תוך דקות, וההבדלים מודגשים. VRT חוסכת עד 20 שעות של בדיקות ידניות בחודש בפרויקט ממוצע — זה בערך $1,000 במחיר של $50 לשעה. היא גם תופסת רגרסיות שאינן נראות לעין — כמו שינוי של 1px או שינוי מרווח.
כלים ל-VRT
| כלי | סוג | עלות | אינטגרציית Bitrix |
|---|---|---|---|
| Playwright + snapshot | אירוח עצמי | חינם | דרך CI/CD |
| Percy | SaaS | החל מ-$50 לחודש | API |
| Chromatic | SaaS | בתשלום | דרך Storybook |
Playwright עם בדיקות snapshot מובנות הוא האפשרות המשולבת ביותר אם המסגרת כבר בשימוש ל-E2E. מניסיוננו, הוא מהיר פי 3–5 מ-Percy לפרויקטים קטנים ואינו דורש מנוי חודשי. עבור רוב פרויקטי 1C-Bitrix זה מספיק. אם אתם צריכים פלטפורמה מתקדמת עם ניתוח הבדלים ואירוח צילומי מסך, Percy מתאים, אך העלות שלו יכולה להיות גבוהה יותר בשימוש כבד.
איך להגדיר בדיקות Snapshot ב-Playwright
שלב 1: התקינו את Playwright: npm init playwright@latest. שלב 2: הגדירו את הקובץ playwright.config.ts:
// 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-анимации
},
},
});
שלב 3: צרו בדיקות לדפים מרכזיים: דף הבית, קטלוג, כרטיס מוצר, סל קניות, תשלום.
בדיקות ויזואליות בסיסיות ל-Bitrix
// 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');
const timer = document.querySelector('.sale-timer');
if (timer) await page.evaluate(() => (document.querySelector('.sale-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');
});
});
תצוגת מובייל
הוסיפו פרויקט נפרד בקונפיגורציה לבדיקות מובייל:
// 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/**',
},
]; מיסוך אלמנטים דינמיים
דפי Bitrix מכילים אלמנטים שמשתנים בכל פעם: מוני מבקרים, טיימרים לפרסום, בלוקים של "נצפה היום" וכדומה. יש למסך אותם:
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
דוגמה ל-pipeline עבור GitHub Actions:
---
# .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/
בכשל בבדיקה, // 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-анимации }, }, }); יכיל שלושה קבצים: baseline, צילום מסך נוכחי, ו-diff עם הבדלים מודגשים.
אינטגרציה עם Bitrix24
ניתן לשלוח הודעות על כשל בבדיקה ל-Bitrix24 דרך REST API או webhooks. יצירת משימות אוטומטיות ב-Bitrix24 בעת זיהוי רגרסיה אפשרית גם כן.מה לעשות עם תוצאות חיוביות שגויות?
תוצאות חיוביות שגויות נובעות מתוכן דינמי (מונים, טיימרים) או שינויים אקראיים (למשל, תוכן שונה בווידג'ט חדשות). פתרון: מסכו אלמנטים כאלה (כפי שהוצג לעיל) או הגדילו את // 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'); const timer = document.querySelector('.sale-timer'); if (timer) await page.evaluate(() => (document.querySelector('.sale-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'); }); }); . אם העיצוב שונה בכוונה, עדכנו את צילומי ה-baseline עם הפקודה // 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/**', }, ]; והתחייבו לצילומים החדשים — המבקר יראה אז שינויים ויזואליים ב-diff יחד עם הקוד.
מה כלול בהתקנה סוהר
- ביקורת על המצב הנוכחי ובחירת 10–15 דפים מרכזיים
- כתיבת בדיקות snapshot לתצוגות דסקטופ ומובייל
- הגדרת CI/CD (GitHub Actions, GitLab CI)
- מיסוך אלמנטים דינמיים והגדרת סובלנות
- אינטגרציה עם הודעות (Telegram, Slack, Bitrix24)
- תיעוד והדרכת צוות
הניסיון הרב שלנו ב-1C-Bitrix עם 150+ פרויקטים מבטיח פריסה יציבה. צרו קשר כדי לדון בפרויקט שלכם — נבחן אותו תוך יום אחד ונספק הצעת מחיר לאחר ניתוח.
אסטרטגיית יישום
| שלב | פעולה | משך |
|---|---|---|
| צילומי baseline | 10–15 דפים מרכזיים בדסקטופ ומובייל | 1–2 ימים |
| אינטגרציית CI | הרצה על PR ל-staging | 0.5 ימים |
| הרחבת כיסוי | רכיבי קטלוג, סל קניות, תשלום | 2–3 ימים |
| פרופיל מובייל | בדיקות נפרדות ל-375px, 768px | יום אחד |
התחילו עם דף הבית, דף הקטלוג, כרטיס המוצר והסל — אלה מכסים 80% מהרגרסיות שמתרחשות במהלך עדכוני תבנית. כאשר העיצוב משתנה בכוונה, עדכנו את ה-baselines עם 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'), ], }); . צילומי מסך מעודכנים מתחייבים כחלק מה-PR — המבקר רואה שינויים ויזואליים לצד הקוד ב-diff.

