Search code examples
javascriptcypressfixtures

How to (can i?) load Cypress fixture inside intercept based on request data?


I have a bunch of fixtures generated by the backend, and named based on the hash of the request body. I am trying to find a way to load fixtures dynamically based on the sent request, something like this:

cy.intercept('POST', '**/login', (req) => {
    const hash = md5(req.body);
    cy.fixture(`${hash}.json`).then(data => {
        req.reply(res => {
            res.statusCode = data.statusCode;
            res.body = data.body;
        })
    })
}).as('response');

cy.visit("/login");

cy.get('input[name="email"]').type('test@email.com');
cy.get('input[name="password"]').type('wrongpassword');
        
cy.contains('button', 'Login').click();

cy.wait('@response');

cy.contains('Invalid credentials.');

But every time I try to load a fixture inside an intercept, I get the following error:

The following error originated from your test code, not from Cypress.

  > A request callback passed to cy.intercept() threw an error while intercepting a request:

Cypress detected that you returned a promise from a command while also invoking one or more cy commands in that promise.

The command that returned the promise was:

  > cy.wait()

The cy command you invoked inside the promise was:

  > cy.fixture()

Is there any way, I could possibly load fixtures dynamically based on something inside the request?


Solution

  • You can just read the fixture first

    cy.fixture('login_incorrect.json').then(data => { // may not need it, but in case...
    
      cy.intercept('POST', '**/login', (req) => {
        const body = JSON.parse(req.body);
        if(body.password === 'wrongpassword') {
          req.reply(res => {
            res.statusCode = data.statusCode;     // data = closure from above
            res.body = data.body;
          })
        } else {
          // load a different fixture based on something, etc.
        }
      }).as('response');
    
    })
    

    Combined fixture

    {
      "put-first-hash-here": { 
        statusCode: ...,
        body: ...
      },
      "put-second-hash-here": { 
        statusCode: ...,
        body: ...
      },
    }
    

    Test

    cy.fixture('combined.json').then(data => { 
    
      cy.intercept('POST', '**/login', (req) => {
        const body = JSON.parse(req.body);
        const hash = md5(req.body);
        if(body.password === 'wrongpassword') {
          req.reply(res => {
            res.statusCode = data[hash].statusCode;
            res.body = data[hash].body;
          })
        } 
      }).as('response');
    
    })