0

how can I save request body to outside variable. I want to do something like this:

let request;
  cy.intercept("POST", "/url**", ( req => {
    request = {...req.body};
    req.reply({
      body: response
    });
  }));

// use the "request" variable
// ...

and want to share this copied variable with other functions, but cy.intercept does not allow you to do this. Are there any workarounds?

Klea
  • 169
  • 7
hamvee
  • 141
  • 3
  • 13

2 Answers2

3

You will need to add a wait to your code, since cy.intercept() is just a declarative event listener. Adding a wait for it's alias ensures that it has been triggered.

Also, since the code is async you will probably need to wrap and alias request to use it in other parts. Using the raw request variable might give you the empty value, depending on context.

Ideally you would do this in a beforeEach() I think. You probably also need to add the trigger for the POST call - is is a cy.visit()?

let request;

cy.intercept("POST", "**/url/**", ( req => {
  request = {...req.body};
  req.reply({
    body: response
  })
})).as('myIntercept')

// Must cy.wait (not cy.get) the first occurrence
cy.wait('@myIntercept') 

cy.wrap(request).as('myRequest')

// use the "request" variable
cy.get('@myRequest').then(request => {...    

or take request from the wait result

cy.intercept("POST", "**/url/**").as('myIntercept')

// Must cy.wait (not cy.get) the first occurrence
cy.wait('@myIntercept').its('request')
  .then(request => {
    ...
  })

// 2nd time use get()
cy.get('@myIntercept').its('request')
  .then(request => {
    ...
  })
Paolo
  • 3,530
  • 7
  • 21
  • Unfortunatelly, this option does not work for me, I've got an error: `CypressError: Timed out retrying after 5000ms: cy.wait() timed out waiting 5000ms for the 1st request to the route: myIntercept. No request ever occurred.` The test didn't even reach the site. The flow in the test was like this: `it("test", () => { mock (); cy.visit ("https://stackoverflow.com/");}) })` where `mock()` is a function in separated module where I wrote code above – hamvee Sep 02 '21 at 04:36
  • If you get that error, it means the `intercept` is not firing, which means the assignment to variable `request` cannot happen. You need to check the string `"/url**"` - are you able to share the actual url you want to catch? – Paolo Sep 02 '21 at 04:45
  • Paolo, thank you for the reply! Unfortunately I can't share url because it's local environment. I will probably decide to abandon the idea of saving the request to a separate outside variable, since Cypress does not allow this to be done in a convenient way out of the box (for intercept option) – hamvee Sep 02 '21 at 04:56
  • Ok, but in case you want to fix the intercept try pasting the full url into the 2nd parameter. – Paolo Sep 02 '21 at 05:00
1

You can use aliases for this.

let somevalue;

describe('Test Suite', () => {
  it('Test case', () => {
    cy.intercept("POST", "/url**").as('urlReq')

    cy.get('@urlReq').then((urlReq) => {
      // urlReq.body will have the intercepted request body
      somevalue = urlReq.body.key
    })
  })
})
Alapan Das
  • 17,144
  • 3
  • 29
  • 52
  • Thank you Alapan, but I would like to achieve saving the request to a variable outside the scope of the arrow function. I need this to be passed between other functions or passed to another function as an argument. In my test framework, the mocks are in a separate module in the form of functions so that I can call them in tests, so I need to store the request outside of `then` scope. – hamvee Sep 01 '21 at 18:38
  • Is there a specific key-value pair from the request body that you're trying to save and reuse? – Alapan Das Sep 01 '21 at 18:43
  • ideally, I would like to save the entire request, but there are only three key-pairs in the current task, so I can save them in three separate variables – hamvee Sep 01 '21 at 19:03
  • I have updated my answer. Now, `somevalue` will have a global scope. You can use it through the test and also pass this as a parameter to other functions. – Alapan Das Sep 01 '21 at 19:08
  • well, propably I'm doing something wrong because I've got an error: Cannot read property 'body' of null `let request;` `export function() { ... cy.intercept({method: "POST", path: "/url**"}, { body: response }).as("catchRequest"); cy.get("catchRequest").then((req) => { request = req.body['key']; }) }` – hamvee Sep 01 '21 at 19:30