Настройка Cypress-тестов для 1С-Битрикс
Cypress — более современная альтернатива Selenium для E2E-тестирования фронтенда Битрикс. Ключевое преимущество: тесты выполняются внутри браузера, имеют полный доступ к DOM и сети, автоматически ждут появления элементов. Flaky-тестов («иногда падает, иногда нет») у Cypress меньше, чем у Selenium, потому что нет гонки условий с явными sleep().
Настройка Cypress-тестов для 1С-Битрикс
Установка и структура
Cypress устанавливается как dev-зависимость в папку шаблона или в корень проекта:
npm install --save-dev cypress
Структура тестов для Битрикс-проекта:
cypress/
e2e/
catalog/
filter.cy.ts
product-card.cy.ts
cart/
add-to-cart.cy.ts
checkout.cy.ts
auth/
login.cy.ts
support/
commands.ts <- кастомные команды
e2e.ts <- глобальные импорты
fixtures/
user.json <- тестовые данные
product.json
cypress.config.ts
cypress.config.ts для Битрикс
import { defineConfig } from 'cypress';
export default defineConfig({
e2e: {
baseUrl: 'https://test.site.ru',
specPattern: 'cypress/e2e/**/*.cy.ts',
supportFile: 'cypress/support/e2e.ts',
viewportWidth: 1280,
viewportHeight: 900,
defaultCommandTimeout: 8000,
requestTimeout: 10000,
video: false,
screenshotOnRunFailure: true,
// Настройки для Битрикс — сессии и CSRF
experimentalModifyObstructiveThirdPartyCode: true,
},
env: {
adminLogin: 'admin',
adminPassword: '', // из переменной окружения CYPRESS_adminPassword
siteSessid: '', // CSRF-токен для API-запросов
},
});
Кастомные команды для Битрикс
// cypress/support/commands.ts
declare global {
namespace Cypress {
interface Chainable {
loginBitrix(login: string, password: string): Chainable<void>;
addToCart(productUrl: string): Chainable<void>;
getBitrixSessid(): Chainable<string>;
}
}
}
Cypress.Commands.add('loginBitrix', (login, password) => {
cy.visit('/');
// Получаем sessid из cookie
cy.getCookie('PHPSESSID').then(() => {
cy.request({
method: 'POST',
url: '/local/ajax/auth.php',
body: { action: 'login', login, password },
}).then(resp => {
expect(resp.body.status).to.eq('success');
});
});
});
Cypress.Commands.add('addToCart', (productUrl) => {
cy.visit(productUrl);
cy.get('[data-action="add-to-cart"]').click();
// Ждём обновления счётчика корзины
cy.get('.cart-counter', { timeout: 5000 }).should('not.have.text', '0');
});
E2E-тест каталога с фильтром
// cypress/e2e/catalog/filter.cy.ts
describe('Умный фильтр каталога', () => {
beforeEach(() => {
cy.visit('/catalog/tools/');
// Ждём загрузки фильтра и товаров
cy.get('.catalog-filter').should('be.visible');
cy.get('.product-list').should('be.visible');
});
it('фильтрует товары по бренду', () => {
cy.get('[data-filter-prop="BRAND"] [value="bosch"]').click();
// Ждём AJAX-обновления (исчезновение лоадера)
cy.get('.catalog-loading').should('not.exist');
// URL должен измениться
cy.url().should('include', 'brand=bosch');
// Все карточки содержат бренд Bosch
cy.get('.product-brand').each($el => {
cy.wrap($el).should('have.text', 'Bosch');
});
});
it('сбрасывает фильтр', () => {
cy.get('[data-filter-prop="BRAND"] [value="bosch"]').click();
cy.get('.catalog-loading').should('not.exist');
cy.get('.filter-reset-btn').click();
cy.get('.catalog-loading').should('not.exist');
cy.url().should('not.include', 'brand=bosch');
});
it('отображает корректное количество товаров в счётчике фильтра', () => {
// Проверяем, что счётчик обновляется при изменении фильтра
cy.get('[data-filter-prop="BRAND"] [value="makita"]').click();
cy.get('.catalog-loading').should('not.exist');
cy.get('.products-count').invoke('text').then(text => {
const count = parseInt(text.replace(/\D/g, ''));
cy.get('.product-card').should('have.length', Math.min(count, 24)); // 24 — pageSize
});
});
});
Тест формы заказа
// cypress/e2e/cart/checkout.cy.ts
describe('Оформление заказа', () => {
it('успешно оформляет заказ гостем', () => {
// Добавляем товар в корзину через UI
cy.addToCart('/catalog/tools/drills/bosch-gsh/');
cy.visit('/cart/');
cy.get('.checkout-btn').click();
// Заполняем форму заказа
cy.get('#ORDER_PROP_1').type('Иван Иванов'); // Имя
cy.get('#ORDER_PROP_2').type('[email protected]'); // Email
cy.get('#ORDER_PROP_3').type('+79001234567'); // Телефон
cy.get('#ORDER_PROP_6').type('г. Москва, ул. Тестовая, 1'); // Адрес
// Выбираем доставку
cy.get('[name="DELIVERY_ID"][value="1"]').click();
// Выбираем оплату
cy.get('[name="PAY_SYSTEM_ID"][value="1"]').click();
// Принимаем пользовательское соглашение
cy.get('#agree').check();
// Отправляем заказ
cy.get('.order-submit-btn').click();
// Ждём страницы успешного заказа
cy.url({ timeout: 15000 }).should('include', '/personal/order/');
cy.get('.order-success-message').should('be.visible');
});
});
Перехват AJAX-запросов к Битрикс
// Мокирование AJAX-ответа для изолированного тестирования
cy.intercept('POST', '/local/ajax/cart.php', {
statusCode: 200,
body: {
status: 'success',
cart: { items: [], totalCount: 0, totalPrice: 0 },
},
}).as('cartRequest');
cy.get('[data-action="add-to-cart"]').click();
cy.wait('@cartRequest').its('response.statusCode').should('eq', 200);
Сроки
| Задача | Сроки |
|---|---|
| Установка Cypress, базовая конфигурация, кастомные команды | 4–8 часов |
| E2E-тесты критических сценариев (5–10 тестов) | 1–2 дня |
| Полный набор тестов каталога + корзина + чекаут | 2–4 дня |
| Интеграция в GitHub Actions / GitLab CI | 4–8 часов |







