E2E тестирование

E2E (end-to-end) тестирование Slim Sel ect охватывает проверку поведения компонента в условиях, максимально приближенных к реальному использованию в браузере. В отличие от unit- и integration-тестов, здесь проверяется не внутренняя логика библиотеки, а взаимодействие пользователя с DOM-элементами, событиями, асинхронными данными и визуальным состоянием интерфейса.

Slim Select представляет собой кастомизированный <select>-компонент с поддержкой поиска, мультивыбора, динамической загрузки и кастомного рендера. Это делает E2E-тестирование ключевым этапом проверки корректности поведения, особенно в сложных UI-сценариях.


Архитектура E2E тестирования Slim Select

В основе E2E-тестов лежит моделирование пользовательских действий:

  • клик по инпуту или контейнеру Slim Select
  • открытие dropdown-списка
  • выбор одного или нескольких значений
  • ввод текста в поиск
  • удаление выбранных значений
  • взаимодействие с клавиатурой
  • проверка синхронизации состояния <select> и UI

Типовая структура теста включает:

  • подготовку DOM-страницы
  • инициализацию Slim Select
  • выполнение действий через браузерный драйвер
  • проверку состояния DOM и значений <select>

Подготовка тестового окружения

E2E тестирование Slim Select чаще всего реализуется с использованием:

  • Cypress
  • Playwright
  • Selenium WebDriver

Каждый инструмент взаимодействует с реальным браузером, что позволяет тестировать визуальные и событийные аспекты Slim Select.

Пример HTML-страницы для тестов:

<select id="country">
  <option value="kz">Kazakhstan</option>
  <option value="ru">Russia</option>
  <option value="us">USA</option>
</select>

<script>
  new SlimSelect({
    select: '#country'
  });
</script>

Базовый сценарий E2E: выбор значения

Основной сценарий проверки — выбор одного элемента.

Cypress пример

describe('Slim Select single select', () => {
  it('selects value fr om dropdown', () => {
    cy.visit('/index.html');

    cy.get('.ss-single-selected').click();
    cy.get('.ss-option').contains('USA').click();

    cy.get('sel ect#country').should('have.value', 'us');
  });
});

Проверяется:

  • открытие dropdown
  • отображение списка опций
  • выбор элемента
  • синхронизация с оригинальным <select>

Проверка мультивыбора

Slim Select поддерживает режим isMultiple: true, который требует проверки массива значений.

new SlimSelect({
  select: '#countries',
  isMultiple: true
});

E2E сценарий:

it('selects multiple values', () => {
  cy.visit('/multi.html');

  cy.get('.ss-multi-selected').click();
  cy.contains('.ss-option', 'Kazakhstan').click();
  cy.contains('.ss-option', 'Russia').click();

  cy.get('select#countries')
    .find('option:selected')
    .should('have.length', 2);
});

Проверяется:

  • добавление нескольких тегов
  • корректное обновление DOM
  • сохранение состояния в <select>

Проверка поиска (search input)

Slim Select включает встроенный фильтр, который динамически скрывает опции.

it('filters options by search', () => {
  cy.visit('/search.html');

  cy.get('.ss-single-selected').click();
  cy.get('.ss-search input').type('Kaz');

  cy.get('.ss-option')
    .should('have.length', 1)
    .and('contain', 'Kazakhstan');
});

Ключевые аспекты тестирования:

  • ввод текста в search input
  • фильтрация списка
  • обновление DOM без перезагрузки
  • корректная работа debounce (если включён)

Асинхронная загрузка данных

Slim Select может использовать remote data source через ajax-конфигурацию. E2E тестирование таких сценариев требует контроля сетевых запросов.

Перехват API (Cypress intercept)

cy.intercept('GET', '/api/countries', {
  statusCode: 200,
  body: [
    { text: 'Kazakhstan', value: 'kz' },
    { text: 'Russia', value: 'ru' }
  ]
}).as('getCountries');

Тест:

it('loads options asynchronously', () => {
  cy.visit('/async.html');

  cy.wait('@getCountries');

  cy.get('.ss-single-selected').click();
  cy.get('.ss-option').should('have.length', 2);
});

Проверяется:

  • корректность запроса
  • обработка ответа
  • рендеринг опций

Проверка удаления значений (multi-select)

Удаление выбранных элементов является отдельным UI-сценарием.

it('removes selected item', () => {
  cy.visit('/multi.html');

  cy.get('.ss-multi-selected').click();
  cy.contains('.ss-option', 'USA').click();

  cy.get('.ss-value-delete').click();

  cy.get('select#countries')
    .find('option:selected')
    .should('have.length', 0);
});

Проверяется:

  • наличие delete-кнопки
  • корректное обновление состояния
  • синхронизация UI и <select>

Клавиатурная навигация

Slim Select поддерживает навигацию через клавиши:

  • ArrowDown / ArrowUp
  • Enter
  • Escape

Пример E2E сценария

it('supports keyboard navigation', () => {
  cy.visit('/index.html');

  cy.get('.ss-single-selected').focus().type('{downarrow}{downarrow}{enter}');

  cy.get('select#country')
    .should('have.value', 'ru');
});

Проверяется:

  • фокусировка компонента
  • навигация по списку
  • выбор через Enter

Проверка закрытия dropdown

Dropdown должен корректно закрываться при внешнем клике или нажатии Escape.

it('closes dropdown on escape', () => {
  cy.visit('/index.html');

  cy.get('.ss-single-selected').click();
  cy.get('body').type('{esc}');

  cy.get('.ss-content').should('not.be.visible');
});

Проверка состояния disabled

Slim Select может работать с disabled <select>.

it('does not open disabled select', () => {
  cy.visit('/disabled.html');

  cy.get('.ss-single-selected').click();

  cy.get('.ss-content').should('not.exist');
});

Проверяется:

  • блокировка взаимодействия
  • отсутствие dropdown в DOM или его неактивность

Playwright сценарии

Playwright позволяет описывать более строгие и детерминированные E2E тесты.

import { test, expect } fr om '@playwright/test';

test('select value', async ({ page }) => {
  await page.goto('/index.html');

  await page.click('.ss-single-selected');
  await page.click('text=USA');

  const value = await page.$eval('#country', el => el.value);
  expect(value).toBe('us');
});

Особенности:

  • авто-ожидания DOM-состояния
  • стабильная работа с async UI
  • контроль сетевых запросов

Selenium сценарии

Selenium WebDriver используется в классических QA-инфраструктурах.

const { Builder, By } = require('selenium-webdriver');

(async function testSlimSelect() {
  let driver = await new Builder().forBrowser('chrome').build();

  await driver.get('http://localhost:3000');

  await driver.findElement(By.css('.ss-single-selected')).click();
  await driver.findElement(By.xpath("//*[text()='USA']")).click();

  let value = await driver.findElement(By.id('country')).getAttribute('value');

  console.log(value);
})();

Проверка повторного рендера и стабильности DOM

Slim Select может пересоздавать DOM при обновлении данных, поэтому E2E тесты часто включают проверку устойчивости селектора.

it('maintains state after re-render', () => {
  cy.visit('/dynamic.html');

  cy.get('.ss-single-selected').click();
  cy.contains('.ss-option', 'USA').click();

  cy.reload();

  cy.get('select#country').should('have.value', 'us');
});

Проверка множественных экземпляров Slim Select

На одной странице может быть несколько компонентов:

it('handles multiple instances', () => {
  cy.visit('/multi-selects.html');

  cy.get('#select1 .ss-single-selected').click();
  cy.contains('.ss-option', 'USA').click();

  cy.get('#select2 .ss-single-selected').click();
  cy.contains('.ss-option', 'Kazakhstan').click();

  cy.get('#select1 select').should('have.value', 'us');
  cy.get('#select2 select').should('have.value', 'kz');
});

Типовые проблемы E2E тестирования Slim Select

При автоматизированной проверке часто проявляются особенности:

  • асинхронное обновление DOM после кликов
  • задержки рендера dropdown
  • переинициализация компонента при изменении данных
  • нестабильные селекторы .ss-option
  • конфликты при нескольких экземплярах

Эти факторы требуют опоры на стабильные атрибуты и проверку состояния через оригинальный <select>, а не только UI-слой.