Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Як тестувати роботу з DOM без фреймворку: Testing Library, jsdom і happy-dom?

Код, що працює з DOM (Alpine-компоненти, скрипти на сторінках Blade, веб-компоненти), потребує документа. У Node.js його немає - тому тест запускають у середовищі, що імітує браузер.

Середовища Vitest:

Середовище Що це Особливості
node без DOM (за замовчуванням) для чистої логіки
jsdom реалізація DOM на JavaScript найповніша сумісність, повільніший
happy-dom легша реалізація DOM швидший, але деякі API відсутні чи поводяться інакше
Browser Mode справжній браузер через Playwright реальний рендеринг, макет, події
// vitest.config.js
export default defineConfig({
  test: { environment: 'jsdom' },
});

Чи лише для одного файлу - коментарем на початку: // @vitest-environment happy-dom.

Що jsdom і happy-dom не вміють: макет і розміри (getBoundingClientRect повертає нулі), прокрутку, IntersectionObserver, CSS-анімації, справжню навігацію. Тести, що від цього залежать, - для браузера.

DOM Testing Library - пошук елементів так, як їх бачить користувач:

import { screen, within } from '@testing-library/dom';
import userEvent from '@testing-library/user-event';
import { mountSubscribeForm } from './subscribe';

it('показує помилку для неправильної пошти', async () => {
  document.body.innerHTML = '<div id="app"></div>';
  mountSubscribeForm(document.getElementById('app'));

  const user = userEvent.setup();
  await user.type(screen.getByLabelText('Email'), 'not-an-email');
  await user.click(screen.getByRole('button', { name: 'Підписатися' }));

  expect(await screen.findByRole('alert')).toHaveTextContent('Неправильна адреса');
});

Пріоритет запитів:

  1. getByRole з name - як елемент бачать допоміжні технології;
  2. getByLabelText - поля форм;
  3. getByText - звичайний текст;
  4. getByTestId - останній варіант, коли нічого іншого немає.

Пошук за роллю водночас перевіряє доступність: якщо кнопку не знайти за роллю й назвою, її не знайде і програма читання з екрана.

getBy / queryBy / findBy: getBy кидає помилку, якщо елемента немає; queryBy повертає null (для перевірки відсутності); findBy - асинхронний, чекає появи елемента.

@testing-library/jest-dom додає зручні матчери: toBeVisible, toBeDisabled, toHaveValue, toHaveTextContent (працює і з Vitest).

Не тестуйте розмітку: перевірки на кшталт «третій div має клас error» ламаються від кожної зміни верстки, хоча поведінка не змінилася.

Докладніше в документації: DOM Testing Library

Схожі питання