Работа с WebSocket соединениями

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

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

Открытие WebSocket соединения

Для начала работы с WebSocket в Playwright необходимо установить соединение. Это делается с помощью метода page.waitForEvent('websocket'), который позволяет дождаться момента, когда страница установит WebSocket соединение. Также существует возможность прослушивания сообщений, поступающих по WebSocket каналу.

Пример кода для подключения к WebSocket:

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

test('WebSocket connection', async ({ page }) => {
  // Навигация на страницу
  await page.goto('https://example.com');
  
  // Ожидание открытия WebSocket соединения
  const [websocket] = await Promise.all([
    page.waitForEvent('websocket'),
    page.click('button#open-websocket') // действия на странице, которые инициируют WebSocket соединение
  ]);

  // Проверка успешного соединения
  expect(websocket).toBeDefined();
});

Этот код запускает браузер, переходит на указанную страницу и ожидает, что произойдёт событие websocket, то есть что будет установлено WebSocket соединение. После того как соединение будет установлено, тест проверяет, что объект websocket не является undefined.

Прослушивание сообщений WebSocket

После установления соединения можно начать слушать сообщения, отправляемые через WebSocket. Для этого используется событие message, которое срабатывает при получении данных по открытой связи.

Пример кода для прослушивания сообщений:

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

test('Receive WebSocket messages', async ({ page }) => {
  await page.goto('https://example.com');
  
  // Ожидание открытия WebSocket соединения
  const [websocket] = await Promise.all([
    page.waitForEvent('websocket'),
    page.click('button#open-websocket')
  ]);

  // Перехват сообщений, поступающих по WebSocket
  websocket.on('message', (message) => {
    console.log('Received message: ', message);
    expect(message).toContain('expected message content');
  });

  // Действия на странице, которые приводят к отправке сообщения по WebSocket
  await page.click('button#send-message');
});

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

Проверка взаимодействия с сервером через WebSocket

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

Пример теста, который проверяет отправку и получение сообщения по WebSocket:

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

test('Test WebSocket message exchange', async ({ page }) => {
  await page.goto('https://example.com');
  
  // Ожидание установки WebSocket соединения
  const [websocket] = await Promise.all([
    page.waitForEvent('websocket'),
    page.click('button#open-websocket')
  ]);

  // Ожидание получения первого сообщения от сервера
  const serverMessagePromise = new Promise((resolve) => {
    websocket.on('message', (message) => {
      resolve(message);
    });
  });

  // Отправка сообщения на сервер через WebSocket
  await page.fill('textarea#message-input', 'Hello, server!');
  await page.click('button#send-message');

  // Получение ответа от сервера
  const message = await serverMessagePromise;
  expect(message).toContain('Hello, client!');
});

Этот тест выполняет следующие шаги:

  1. Ожидает установления WebSocket соединения.
  2. Отправляет сообщение через интерфейс страницы.
  3. Ожидает ответ от сервера.
  4. Проверяет, что ответ соответствует ожидаемому содержимому.

Обработка закрытия WebSocket соединения

После завершения работы с WebSocket соединением необходимо правильно его закрыть. В Playwright для этого используется событие close. Это событие срабатывает, когда сервер или клиент закрывает WebSocket соединение.

Пример обработки закрытия соединения:

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

test('WebSocket close event', async ({ page }) => {
  await page.goto('https://example.com');
  
  // Ожидание установления WebSocket соединения
  const [websocket] = await Promise.all([
    page.waitForEvent('websocket'),
    page.click('button#open-websocket')
  ]);
  
  // Подписка на событие закрытия WebSocket
  const closePromise = new Promise((resolve) => {
    websocket.on('close', () => {
      resolve('Connection closed');
    });
  });

  // Закрытие соединения
  await page.click('button#close-websocket');

  // Ожидание закрытия соединения
  const closeMessage = await closePromise;
  expect(closeMessage).toBe('Connection closed');
});

Этот код демонстрирует, как можно тестировать корректность закрытия WebSocket соединения. После того как соединение закрывается, происходит срабатывание события close, и тест проверяет, что оно произошло.

Проблемы и ошибки при работе с WebSocket

Одной из проблем, с которыми могут столкнуться разработчики при тестировании WebSocket, является неправильная обработка ошибок соединения. Playwright предоставляет возможность подписаться на события error и close, что позволяет отлавливать ошибки при установлении соединения или в процессе обмена данными.

Пример обработки ошибок:

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

test('WebSocket error handling', async ({ page }) => {
  await page.goto('https://example.com');
  
  // Ожидание установки WebSocket соединения
  const [websocket] = await Promise.all([
    page.waitForEvent('websocket'),
    page.click('button#open-websocket')
  ]);
  
  // Обработка ошибок
  websocket.on('error', (error) => {
    console.error('WebSocket error: ', error);
    expect(error).toBeNull();  // Проверка отсутствия ошибок
  });

  // Действие, которое должно привести к ошибке
  await page.click('button#cause-error');
});

Этот пример показывает, как ловить ошибки WebSocket и удостоверяться в том, что они не возникают в процессе тестирования.

Заключение

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