WebSocket предоставляет двусторонний канал связи между клиентом и
сервером, позволяя обмениваться данными в режиме реального времени. В
отличие от HTTP-запросов, где клиент инициирует каждый запрос, WebSocket
соединение открывается один раз, а сервер может отправлять данные в
любой момент. В контексте тестирования это создаёт особые задачи:
стандартные методы перехвата HTTP-запросов (cy.intercept)
не работают напрямую с WebSocket, поэтому требуется использование других
подходов.
Для работы с WebSocket в Cypress можно использовать встроенные
браузерные объекты WebSocket или сторонние библиотеки,
например ws или socket.io-client. Основная
идея заключается в создании «шпиона» для соединения, который
перехватывает сообщения, отправляемые и получаемые клиентом.
Пример базового подключения к WebSocket в тесте Cypress:
describe('WebSocket тестирование', () => {
it('перехватывает сообщения от сервера', () => {
cy.window().then((win) => {
const ws = new win.WebSocket('ws://localhost:8080');
ws.onmess age = (event) => {
console.log('Сообщение от сервера:', event.data);
};
ws.ono pen = () => {
ws.send(JSON.stringify({ type: 'ping' }));
};
});
});
});
В этом примере создаётся WebSocket соединение внутри контекста окна
браузера, что позволяет напрямую взаимодействовать с объектом
WebSocket, отправлять и получать сообщения.
cy.intercept для WebSocket через HTTP-апгрейдХотя cy.intercept не работает с обычными WebSocket
сообщениями, он может отслеживать HTTP-запросы на установку соединения
(Upgrade), что позволяет проверять успешное
подключение:
cy.intercept({
url: '/socket',
headers: { upgrade: 'websocket' },
}).as('wsConnect');
cy.visit('/');
cy.wait('@wsConnect').then((interception) => {
expect(interception.response.statusCode).to.eq(101);
});
statusCode 101 означает успешное обновление соединения
до WebSocket. Такой подход полезен для проверки того, что клиент
действительно подключается к серверу.
cy.stubДля тестирования логики обработки сообщений можно заменить
стандартный объект WebSocket на «заглушку»
(stub), которая записывает все отправленные и полученные
данные. Этот метод особенно удобен для unit-тестов или симуляции
сообщений от сервера.
describe('Stub WebSocket', () => {
it('логирует отправку и получение сообщений', () => {
cy.window().then((win) => {
const messages = [];
const OriginalWebSocket = win.WebSocket;
cy.stub(win, 'WebSocket').callsFake((url) => {
const ws = new OriginalWebSocket(url);
ws.send = cy.stub().callsFake((msg) => {
messages.push({ type: 'sent', msg });
OriginalWebSocket.prototype.send.call(ws, msg);
});
ws.addEventListener('message', (event) => {
messages.push({ type: 'received', msg: event.data });
});
return ws;
});
cy.visit('/');
cy.window().then(() => {
console.log(messages);
});
});
});
});
Этот способ позволяет не только проверять отправленные сообщения, но и создавать искусственные события для проверки реакции приложения.
Для тестирования поведения клиентского кода при получении
определённых событий можно вручную отправлять сообщения через
заглушенный объект WebSocket:
ws.onmessage({ data: JSON.stringify({ type: 'update', payload: { value: 42 } }) });
Это позволяет имитировать любые сценарии, включая ошибки сервера, неожиданные данные или задержки в доставке сообщений.
Если требуется проверка взаимодействия с настоящим WebSocket
сервером, Cypress позволяет выполнять асинхронные операции через
cy.wrap и промисы. Пример:
cy.window().then((win) => {
const ws = new win.WebSocket('ws://localhost:8080');
cy.wrap(new Cypress.Promise((resolve) => {
ws.onmess age = (event) => {
if (JSON.parse(event.data).type === 'ready') {
resolve(event.data);
}
};
})).then((data) => {
expect(JSON.parse(data).type).to.eq('ready');
});
});
Использование промисов и cy.wrap обеспечивает корректную
синхронизацию Cypress с асинхронным WebSocket кодом, что предотвращает
случайные ошибки в тестах.
Для отладки WebSocket тестов полезно сохранять все отправленные и
полученные сообщения в массив или объект, а затем выводить их через
cy.log или console.log. Это помогает
отслеживать последовательность событий и выявлять ошибки логики
приложения.
Перехват WebSocket сообщений в Cypress требует комбинирования
нескольких техник: наблюдение за соединением через
cy.intercept, использование заглушек для перехвата
сообщений и асинхронного тестирования с cy.wrap. Такой
подход обеспечивает гибкость тестирования как unit-уровня, так и
интеграционного взаимодействия в реальном времени.