В тестировании веб-приложений с использованием Playwright возникает необходимость имитировать различные сетевые взаимодействия. Одним из таких взаимодействий является использование WebSocket — протокола для двусторонней связи между клиентом и сервером. Мокирование WebSocket помогает создавать предсказуемую среду для тестов, когда важно контролировать и симулировать обмен сообщениями по этому протоколу.
WebSocket — это технология, обеспечивающая постоянное двустороннее соединение между клиентом и сервером через один TCP-соединение. В отличие от традиционных HTTP-запросов, WebSocket позволяет серверу отправлять данные клиенту без необходимости его опроса. Это идеально подходит для приложений с реальным временем, таких как чаты, игры, финансовые платформы и другие.
Playwright, как инструмент для автоматизации браузеров, позволяет взаимодействовать с WebSocket. Однако по умолчанию в Playwright нет встроенной поддержки мокирования WebSocket, как, например, для HTTP-запросов. Тем не менее, благодаря гибкости Playwright, можно с легкостью реализовать моки для WebSocket-сообщений.
Для начала необходимо установить Playwright и подготовить окружение для работы с тестами. Если Playwright еще не установлен, это можно сделать с помощью следующей команды:
npm install playwright
После этого можно настроить базовый тестовый файл с помощью
библиотеки тестирования, такой как jest или
mocha. Для примера будем использовать стандартный
test из Playwright.
const { test, expect } = require('@playwright/test');
Основной подход к мокированию WebSocket в Playwright заключается в
перехвате и изменении сообщений, которые отправляются или получаются
через WebSocket. Playwright предоставляет возможности для работы с
событиями WebSocket, такими как open, message
и close. Для того чтобы имитировать поведение WebSocket,
можно перехватывать события, отправлять ответные сообщения или изменять
содержимое данных.
Пример мокирования WebSocket-соединения выглядит следующим образом:
test('Мокирование WebSocket сообщений', async ({ page }) => {
// Создание мока WebSocket-соединения
const wsMock = await page.context().route('**/ws', (route, request) => {
const ws = new WebSocket(request.url());
// Подключение к WebSocket и установка событий
ws.on('open', () => {
ws.send(JSON.stringify({ message: 'Привет, клиент!' }));
});
ws.on('message', (data) => {
const message = JSON.parse(data);
// Важно: обработка данных, поступающих через WebSocket
if (message.command === 'ping') {
ws.send(JSON.stringify({ command: 'pong' }));
}
});
route.fulfill({ status: 200 });
});
// Эмулируем запуск клиентской стороны, которая подключается к WebSocket
await page.goto('https://example.com'); // URL вашего приложения
await page.evaluate(() => {
const ws = new WebSocket('wss://example.com/ws');
ws.ono pen = () => console.log('WebSocket подключен');
ws.onmess age = (event) => console.log('Получено сообщение:', event.data);
});
// Проверка взаимодействия с моком
await expect(page).toHaveText('Привет, клиент!');
});
В этом примере создается мок-соединение WebSocket с сервером, который отправляет сообщение в ответ на подключение. После этого клиентская сторона подключается к этому WebSocket и взаимодействует с ним.
При тестировании более сложных приложений важно учитывать, что WebSocket-соединения могут быть многократными. Иногда приложение может устанавливать несколько соединений, которые обрабатываются отдельно. В таких случаях важно правильно управлять сессиями WebSocket.
Для мокирования нескольких подключений можно использовать массив сессий WebSocket, которые будут хранить состояние каждого подключения. Такой подход может быть полезен при тестировании многозадачных или многопользовательских сценариев.
test('Мокирование нескольких WebSocket соединений', async ({ page }) => {
let connections = [];
const wsMock = await page.context().route('**/ws', (route, request) => {
const ws = new WebSocket(request.url());
connections.push(ws);
ws.on('open', () => {
ws.send(JSON.stringify({ message: 'Соединение установлено' }));
});
ws.on('message', (data) => {
const message = JSON.parse(data);
if (message.command === 'ping') {
ws.send(JSON.stringify({ command: 'pong' }));
}
});
route.fulfill({ status: 200 });
});
// Подключение нескольких клиентов
for (let i = 0; i < 3; i++) {
await page.evaluate((index) => {
const ws = new WebSocket(`wss://example.com/ws?client=${index}`);
ws.ono pen = () => console.log(`WebSocket ${index} подключен`);
ws.onmess age = (event) => console.log(`Получено сообщение от клиента ${index}:`, event.data);
}, i);
}
// Проверка взаимодействия с моками
await expect(page).toHaveText('Соединение установлено');
});
Для упрощения мокирования нескольких сообщений можно использовать специальную утилиту или библиотеку для управления состоянием WebSocket-соединений. Такая утилита позволит централизованно управлять всеми подключениями и их состояниями, что делает тесты более читаемыми и легче поддерживаемыми.
Пример использования WebSocketMock может быть следующим:
const WebSocketMock = require('mock-websocket');
test('Использование WebSocketMock для мокирования', async ({ page }) => {
const mockServer = new WebSocketMock.Server('wss://example.com/ws');
mockServer.on('connection', (socket) => {
socket.on('message', (data) => {
const message = JSON.parse(data);
if (message.command === 'hello') {
socket.send(JSON.stringify({ command: 'hello', response: 'world' }));
}
});
});
await page.goto('https://example.com');
await page.evaluate(() => {
const ws = new WebSocket('wss://example.com/ws');
ws.ono pen = () => ws.send(JSON.stringify({ command: 'hello' }));
ws.onmess age = (event) => console.log('Ответ от сервера:', event.data);
});
await expect(page).toHaveText('Ответ от сервера: {"command":"hello","response":"world"}');
});
В этом примере используется библиотека mock-websocket,
которая позволяет легко моки WebSocket-сервер и подключаться к нему с
помощью стандартных API.
Мокирование WebSocket в Playwright позволяет тестировать приложения с реальными WebSocket-соединениями, не завися от реальных серверов. Это дает возможность гибко управлять поведением соединений, тестировать сценарии, связанные с обработкой сообщений, и эмулировать взаимодействие с сервером. Использование событий WebSocket и моков позволяет создавать стабильные и предсказуемые тесты для взаимодействия с сервером в реальном времени.