Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MSW intercepts plain WebSocket but fails to intercept Socket.IO connections #12

Open
ccpu opened this issue Feb 16, 2025 · 3 comments · May be fixed by socketio/socket.io#5315
Open

MSW intercepts plain WebSocket but fails to intercept Socket.IO connections #12

ccpu opened this issue Feb 16, 2025 · 3 comments · May be fixed by socketio/socket.io#5315

Comments

@ccpu
Copy link
Contributor

ccpu commented Feb 16, 2025

I'm encountering a problem in my local development environment when using MSW with Socket.IO. For some strange reason, MSW is able to intercept a plain WebSocket connection when I use:

new WebSocket("ws://localhost:3000/socket.io/?EIO=4&transport=websocket");

However, it fails to intercept when I use the Socket.IO client:

const socket = io("ws://localhost:3000", {
  retries: 1,
  transports: ["websocket"],
  port: 3000,
});
socket.connect();

Note that Socket.IO client automatically appends /socket.io/ to the URL, so both are attempting to connect to the same endpoint.

I have created a minimal reproduction:

The GitHub repo might be more reliable for reproduction.

Any idea what I might be doing wrong or what modifications are needed to allow MSW to intercept Socket.IO connections as it does with a plain WebSocket?

Thanks in advance for your help!

@kettanaito
Copy link
Member

Hi, @ccpu. Thanks for reporting this.

I think you should drop /socket.io/ from the path. That's internal path for SocketIO, you shouldn't tap into that (here).

Please give that a try and let me know if that helps.

Following the Debugging runbook might also help. For example, provide the onUnhandledRequest option to worker.start() and see whether your WS connection is considered unhandled by MSW.

@ccpu
Copy link
Contributor Author

ccpu commented Mar 9, 2025

Hi, @kettanaito, Thanks for the suggestions.

Dropping /socket.io/ from the URL won't help in this case because the Socket.IO client automatically appends this path. To prevent this behavior, we need to use the path option as shown in my code, so it will match the ws.link. Unfortunately, this still isn't working.

Even more puzzling, onUnhandledRequest isn't printing any messages (via console.log).
The strange thing is that using WebSocket directly works fine (when uncommenting this line).

It seems that MSW is unable to mock the Socket.IO connection because Socket.IO uses a specific handshake protocol that's challenging to intercept with MSW's WebSocket mocking system.

@kettanaito
Copy link
Member

Dropping /socket.io/ from the URL won't help in this case because the Socket.IO client automatically appends this path

I know, that's why you shouldn't append/change it yourself. MSW understands the specific SocketIO handshake protocol in the toSocketIo function. In fact, MSW sometimes checks for /socket.io/ in the path, and it must not be coming from your WebSocket link.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants