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

How to check if server is already running on port #62

Closed
Raat opened this issue Nov 30, 2021 · 3 comments
Closed

How to check if server is already running on port #62

Raat opened this issue Nov 30, 2021 · 3 comments

Comments

@Raat
Copy link

Raat commented Nov 30, 2021

I'm trying to integrate mockttp with cypress.
From the cypress test I start and stop the server at port 8001 like this.

import { getRemote } from 'mockttp'
const server = getRemote()

before(async () => {
  await server.start(8001)
})

after(async () => {
  await server.stop()
})

Now the problem is that whenever a code change is made cypress will restart the test at any moment in time so it's not possible to stop the server. At this moment the test restarts and mockttp throws an error because port 8001 is already in use.

How can I check if a port is already in use and if so restart the server?
I tried this and its not working:

  await server.start(8001).catch(() => {
    server.reset()
  })
@pimterry
Copy link
Member

The issue here is that even if start() fails, your server remote client isn't actually connected, which is why you can't reset or use it. Only one client can be connected at a time, because there's some state (like remote callback connections from thenCallback) and behaviour around rule configuration in general that is very difficult to manage in the presence of multiple changing clients. Because of that, there's no way to connect a client to an already running server.

That said, there is a solution to this, which was added recently (#52) specifically for this kind of Cypress usage. To handle that case, you should do something like this:

describe("Your test suite", () => {
	let server;

	beforeEach(async () => {
        // Try to clean up nicely, if we have a server still running & accessible
        if (server) await server.stop();

	    // As a backup, make sure that we've always cleaned up *everything*, in case
	    // a server from some other page load was still running:
	    await mockttp.resetStandalone();

	    // Then start server again from scratch:
	    server = mockttp.getRemote();
	    await server.start();
	});

   it("a test", () => {
       // ...use 'server' for testing
   });
}

This does a couple of things:

  • It stops the server before tests, not afterwards - this is useful because in Cypress you often want mocks to keep running so you can easily explore your application (https://docs.cypress.io/guides/references/best-practices#Using-after-or-afterEach-hooks). To do this, you have to keep a reference to the server between tests, as here.
  • It calls mockttp.resetStandalone() to completely reset all servers, so you have a clean slate every time (but it still calls stop() first where possible, because a clean shutdown avoids some possible issues in normal use)
  • Then it starts the server as normal.

Does that work for you?

@Raat
Copy link
Author

Raat commented Nov 30, 2021

This is perfect, thanks Tim!

@pimterry
Copy link
Member

Ok, great! I'll close this for now, but feel free to open a new issue if you run into more problems.

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

No branches or pull requests

2 participants