1

I'm having a hard time trying to mock a simple api request from a different port than the frontend. The code below is returning: Timed out retrying after 5000ms: cy.wait() timed out waiting 5000ms for the 1st request to the route: convos. No request ever occurred.

cy.intercept("GET", "http://localhost:4000/conversations", {
  fixture: "conversations.json",
}).as("convos");

cy.visit("http://localhost:3000/conversations");

cy.wait("@convos").then((req) => {
  console.log(req);
});

Any idea what I might be doing wrong here?

UPDATE

I found the problem (but not the solution). Since I'm working with Nuxt, this specific api call is made with Nuxt's backend, so Cypress can't intercept it. Now I need to find a way for Cypress to intercept api calls made in Nuxt's backend.

2nd UPDATE

So the "solution" I found on the internet is the one below. But it doesn't work for me. The frontend page I'm visiting is throwing an Internal Server Error 500.

in cypress.config.ts inside setupNodeEvents:

      let server: any; // static reference to the mock server

      on("task", {
        mockServer({
          interceptUrl,
          fixture,
        }: {
          interceptUrl: string;
          fixture: string;
        }) {
          const fs = require("fs");
          const http = require("http");
          const { URL } = require("url");

          if (server) server.close(); // close any previous instance

          const url = new URL(interceptUrl);
          server = http.createServer((req: any, res: any) => {
            if (req.url === url.pathname) {
              const data = fs.readFileSync(`./cypress/fixtures/${fixture}`);
              res.end(data);
            } else {
              res.end();
            }
          });

          server.listen(url.port);

          return null;
        },
      });
    

In my test before the visit():

cy.task("mockServer", {
  interceptUrl: "http://localhost:4000/conversations",
  fixture: "conversations.json",
});
FabienChn
  • 938
  • 10
  • 17
  • Is your request from your API going to `localhost:3000` or `localhost:4000`? Your `cy.visit()` command goes to 3000, but your intercept is waiting for `4000`. (Definitely possible your FE/BE are running on different ports, just seemed odd at first glance) – agoff Mar 13 '23 at 14:39
  • 1
    my backend and frontend are running on different ports yes. Frontend is on 3000 and backend on 4000. – FabienChn Mar 13 '23 at 14:44
  • Have you validated that your application is actually triggering the request that you are intercepting? You could also set a blanket intercept to capture all requests and view that object after the tests run to see _what_ endpoints are being called and seen by Cypress. – agoff Mar 13 '23 at 14:49
  • Yes, the application triggers the request. The blanket intercept captures also the frontend visits so it makes everything fail. And when trying to intercept "http://localhost:4000/*" nothing is captured – FabienChn Mar 13 '23 at 15:10
  • Sorry, instead of mocking out the requests with the blanket intercept, you'd just pass them through -> `cy.intercept('GET', '**/*', (req) => { req.continue() }).as('blanket')` – agoff Mar 13 '23 at 15:25
  • Ok so I did this and it seems like cypress is not intercepting this api request – FabienChn Mar 13 '23 at 15:43
  • Hmmm - it might make sense to add an arbitrarily high wait (something like `cy.wait(60000)` to see if takes a while for the request to be made, while also looking at the network tab in the dev console (which _can_ contain requests that are being made that Cypress can't access) – agoff Mar 13 '23 at 15:46
  • 1
    Waiting doesn't seem to make any difference. Cypress is not intercepting my api call – FabienChn Mar 14 '23 at 13:31

1 Answers1

1

Sometimes the full URL does not match correctly, but you can differentiate between port 3000 and 4000 inside the intercept.

Use ** prefix to catch both port calls and dynamically assign the alias to the port 4000 call.

cy.intercept(`**/conversations`, (req) => {
  if (req.url.startsWith('http://localhost:4000') {
    req.alias = 'convos')
    req.reply({
      fixture: 'conversations.json'
    })  
  }
})
user16695029
  • 3,365
  • 5
  • 21
  • **/conversations doesn't seem to intercept my api request. It only intercepts the frontend page – FabienChn Mar 14 '23 at 13:25
  • I found the problem. Since I'm working with Nuxt, this specific api call is made with Nuxt's backend, so Cypress can't intercept it. Now I need to find a way for Cypress to intercept api calls made in Nuxt's backend. – FabienChn Mar 14 '23 at 13:51