Server-Sent Events

Server-Sent Events (SSE) представляют собой механизм для передачи данных от сервера к клиенту в реальном времени через HTTP-соединение. Этот подход часто используется для отображения динамически изменяющихся данных, таких как уведомления, обновления статусов и другие события в реальном времени. SSE работает через одностороннюю передачу данных от сервера к клиенту с использованием стандартного HTTP-протокола, что делает его удобным и эффективным для создания приложений с функциональностью реального времени.

Playwright предоставляет возможность тестировать приложения, использующие SSE, через собственные API для взаимодействия с веб-страницами и их компонентами. Рассмотрим, как можно работать с SSE в тестах Playwright.

Особенности работы с SSE

SSE позволяет серверу отправлять данные на клиент в виде потока событий. Каждое событие передается в текстовом формате с указанием имени события и его содержимого. Стандартный формат сообщений SSE выглядит следующим образом:

event: event-name
data: message data

Когда клиент (например, браузер) подключается к серверу, он инициирует HTTP-соединение и начинает слушать поток данных. Сервер отправляет обновления через это соединение по мере необходимости. Важно отметить, что SSE использует однонаправленное соединение — только сервер может отправлять данные клиенту, но не наоборот.

Пример простого SSE-соединения с сервером:

const source = new EventSource('/events');
source.onmess age = function(event) {
    console.log('New message from server:', event.data);
};

Настройка SSE в тестах Playwright

Для тестирования SSE в Playwright важно правильно настроить взаимодействие с сервером и убедиться, что клиент корректно обрабатывает события. В отличие от других технологий, таких как WebSockets, SSE не требует подключения через отдельный канал, и для его работы достаточно обычного HTTP-соединения.

Подключение к SSE

Первый шаг при тестировании SSE — это установка соединения с сервером. В Playwright можно использовать API для эмуляции подключения и взаимодействия с SSE.

const { test, expect } = require('@playwright/test');

test('test SSE events', async ({ page }) => {
  // Открытие страницы, которая слушает SSE
  await page.goto('http://localhost:3000');

  // Ожидание того, что SSE соединение будет установлено
  const sseStatus = await page.waitForSelector('#sse-status');
  await expect(sseStatus).toHaveText('Connected');

  // Ожидание получения события от сервера
  const message = await page.waitForEvent('sse-message');
  expect(message.data).toBe('Test message');
});

В этом примере Playwright взаимодействует с элементом, отображающим статус подключения к SSE, и ожидает получения сообщения от сервера. Когда событие поступает, тест проверяет его данные и подтверждает, что они соответствуют ожиданиям.

Работа с событиями

После установления соединения с SSE-сервером, Playwright предоставляет возможность прослушивать и проверять события, поступающие от сервера. Важным моментом является правильная настройка слушателей для обработки различных типов событий.

test('handle multiple SSE events', async ({ page }) => {
  await page.goto('http://localhost:3000');

  // Прослушка события для первого типа
  page.on('sse-message', (event) => {
    if (event.type === 'event-1') {
      console.log('Received event-1:', event.data);
    }
  });

  // Прослушка события для второго типа
  page.on('sse-message', (event) => {
    if (event.type === 'event-2') {
      console.log('Received event-2:', event.data);
    }
  });

  // Ожидание и проверка получения событий
  const event1Message = await page.waitForEvent('sse-message');
  expect(event1Message.type).toBe('event-1');
  expect(event1Message.data).toBe('Event 1 Data');

  const event2Message = await page.waitForEvent('sse-message');
  expect(event2Message.type).toBe('event-2');
  expect(event2Message.data).toBe('Event 2 Data');
});

Здесь тест проверяет два разных типа событий — event-1 и event-2. С помощью слушателей page.on можно обрабатывать различные типы событий и проверять их содержание.

Обработка ошибок и восстановления соединения

Одним из важных аспектов работы с SSE является обработка ошибок и восстановление соединения в случае его потери. SSE-соединение может быть закрыто по различным причинам, таким как проблемы с сетью или сервером. В таких случаях клиент должен пытаться восстановить соединение.

Playwright позволяет симулировать такие сценарии и проверять поведение клиента. Например, можно проверять, что клиент правильно восстанавливает соединение после его потери:

test('handle SSE connection loss', async ({ page }) => {
  await page.goto('http://localhost:3000');

  // Ожидание первоначального сообщения
  const firstMessage = await page.waitForEvent('sse-message');
  expect(firstMessage.data).toBe('Initial message');

  // Эмуляция потери соединения
  await page.evaluate(() => {
    const source = new EventSource('/events');
    source.close(); // Закрытие соединения
  });

  // Ожидание восстановления соединения
  const reconnectionMessage = await page.waitForEvent('sse-message');
  expect(reconnectionMessage.data).toBe('Reconnected message');
});

В данном примере тест проверяет, что после закрытия соединения клиент автоматически восстанавливает его и продолжает получать сообщения.

Мокирование SSE в тестах

В некоторых случаях может возникнуть необходимость мокировать SSE-соединение для тестирования, например, когда серверное API еще не готово или когда нужно проверить только логику обработки событий в приложении.

Для этого можно использовать возможности Playwright по созданию фиктивных событий, которые эмулируют поведение сервера. Например:

test('mock SSE events', async ({ page }) => {
  await page.goto('http://localhost:3000');

  // Мокирование события
  await page.evaluate(() => {
    const event = new Event('message');
    event.data = 'Mocked event data';
    window.dispatchEvent(event);
  });

  // Ожидание получения события
  const message = await page.waitForEvent('sse-message');
  expect(message.data).toBe('Mocked event data');
});

Мокирование позволяет проверить, как приложение реагирует на различные типы данных, не взаимодействуя с настоящим сервером.

Выводы

Тестирование SSE в Playwright позволяет эффективно проверять работу с сервером в реальном времени, а также взаимодействие клиента с динамическими данными. Возможности Playwright по взаимодействию с событиями и эмуляции соединений позволяют создавать детализированные и точные тесты для таких случаев. Важными аспектами являются правильная настройка прослушивания событий, обработка ошибок и потерянных соединений, а также возможность мокирования данных для тестирования логики приложения.