question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Websocket server doesn't seem to be connecting

See original GitHub issue

I’ve got a project where a node micro service is connected to a rails actioncable websocket.

I’m trying to speck the websocket connection part (regardless of the fact it’s an actioncable websocket behind the scenes) by using jest and jest-websocket-mock and mock-socket.

My ActionCable class connection method looks like this

// lib/classes/action_cable.js
const WebSocket = require('ws');
class ActionCable {
  constructor(url, opts) {
    this.cableURL = url;
    this.origin = opts.origin || 'http://localhost:3000';
    this.headers = opts.headers || {};
    this.connection = null;
    this.connect = null;
  }
  _connect() {
    if (!this.connect) {
      this.connect = new Promise((resolve, reject) => {
        this.connection = new WebSocket(this.cableURL, undefined, { origin: this.origin, headers: this.headers });

        this.connection.onerror = (err) => {
          reject(err);
        };
        this.connection.onclose = () => {
          reject(new Error('Connection closed'));
        };
        this.connection.onopen = () => {
          resolve(this.connection)
        };
      });
    }
    return this.connect;
  }
}

and in my jest test I’ve got this

// tests/classes/action_cable.test.js
import ActionCable from '../../lib/classes/action_cable.js';
import WS from "jest-websocket-mock";
import { Server } from 'mock-socket';

let actioncableInstance = false;

beforeEach(() => {
  actioncableInstance = new ActionCable('ws://localhost:1234', { origin: 'http://localhost:4321' });
});

describe('_connect', () => {
  let WSServer = false;

  beforeEach(() => {
    WSServer = new WS('ws://localhost:1234');
  });
  afterEach(() => {
    WS.clean();
  });

  describe('when WebSocket server refuses the connection', () => {

    beforeEach(() => {
      WSServer.on('connection', (socket) => {
        console.log('received stuff');
        socket.close({ wasClean: false, code: 1003, reason: "NOPE" });
      });
    });

    test('rejects with error and calls _disconnected', async () => {
      expect.assertions(1);
      await expect(actioncableInstance._connect()).rejects;
    });
  });
});

I’ve got a mocks file that seems to no cause errors when I have it like this

// tests/__mocks__/ws.js
const WebSocket = require('mock-socket').WebSocket;

module.exports = WebSocket;

my project tree looks like this

lib
  | classes
    | action_cable.js
tests
  | __mocks__
    | ws.js
  | classes
    | action_cable.test.js

I’m guessing I’ve got something configured wrong but I fail to see what after half a day of trying to get my test to work for this simple case (I haven’t even begun the other cases but I think once I get the connection refused case going I’ll be able to move on to the rest). But in case there’s something else I’m getting a timeout error from my test Async callback was not invoked within the 5000ms timeout specified by jest.setTimeout.Timeout

For a little context this is part of a bigger library of functions I’ve got for general NodeJS usage so I’m not running anything part of a NodeJS framework.

Any help or insight would be appreciated !

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:6 (6 by maintainers)

github_iconTop GitHub Comments

1reaction
romgaincommented, Sep 12, 2020

Oh wow, thanks for your write up!!

The fact that mock-socket uses timeouts really makes it harder to write some tests ☹️

Would you be open to raising a quick PR that would add a small warning about mock timers to the readme?

Thanks again!

1reaction
jwoodrowcommented, Sep 12, 2020

Got it ! maybe this should be added somewhere in the readme but basically everything I said was wrong. The issue was that in this specific test I had this setup for another test jest.useFakeTimers(); removing the line allows the client to connect to the server.

I realised this when I simply created a new action_cable_2.js and action_cable_2.test.js file using the code I provided to you (that didn’t have the jest.useFakeTimers(); line since I didn’t think it was relevant to this test [no timers to test in this function]) and noticed it simply ran (not with the right error but it was running as intended).

Now I do still have an issue that I can’t seem to find any documentation on how to emulate a connection refused (like an origin header not allowed on the server) I wan work around that but if ever you have an idea of how to do this I’d be open to hearing it. I’ll close my ticket for now since I found the issue with my tests.

Thanks for checking in on my issue !

Read more comments on GitHub >

github_iconTop Results From Across the Web

Unable to connect to a websocket - Stack Overflow
I created a PHP websocket using Ratchet. This Websocket is running on port 8080 of my internal server 10.0.4.160 . I am trying...
Read more >
What can I do if I see "Cannot connect to WebSocket" when ...
Go to Control Panel > Login Portal > Advanced > Reverse Proxy. · Select the rule with the issue and click Edit. ·...
Read more >
Can't connect to the server through JS? · Issue #730 - GitHub
I created the server in node and can connect fine through another node client, but in my web app the JS script can't...
Read more >
"WebSocket Unable to Connect” error message, what should I ...
The “WebSocket unable to connect” error message indicates that you are likely working behind a proxy that doesn't support the WebSocket ...
Read more >
Websockets server does not work live - JavaScript - SitePoint
The console gives this error: WebSocket connection to 'wss://localhost:8080/echo' failed: Any clue how I can make this work?
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found