2
votes

My web app sends an API POST request to create an application and returns JSON response. I want to access one particular JSON object from that response. My JSON starts like this

[
    {
        "status_code": 201,
        "body": {
            "created": "2021-01-28T00:00:00Z",
            "modified": "2021-01-28T00:00:00Z",
            "id": "a2d86d17-9b3c-4c4d-ac49-5b9d8f6d6f8f",
            "applicant": {
                "id": "07f1e1d3-0521-401b-813e-3f777f2673c6",
                "status": "Pending",
                "first_name": "",
                "last_name": "",
                "URL": "some onboarding url"

And I wanna take that URL in the JSON response and visit it later in my cypress automation script. Notice that the JSON repsonse starts with a square bracket not a curly bracket, which means, the whole response is an object, I assume?

My cypress script looks like this

        cy.contains('button', 'CONTINUE').click() 
        cy.EmailGen('candidate').then(email => {
            cy.get('#emails\\[0\\]').type(`${email}`)
            cy.wrap(email).as('candidateEmail')
        })
        //writing intercept here, before the Send application button, which triggers the POST req.
        cy.intercept('/hr/v1/applications/invite').as('getURL')
        cy.get('button').contains('SEND APPLICATION').click({ force: true })
        //waiting on the alias of intercept and using interception to print objects from response
        cy.wait('@getURL').then((interception)=> {
            cy.log(interception.response.body.applicant.URL)
        }) 
        
        cy.Logout()

The script executes with no errors. Just that nothing is logged in the cy.log statement. Below is the screen.

execution screen shot I also tried using another method as given below.

cy.intercept('/hr/v1/applications/invite',(req) => {
            req.reply((res=> {
                expect(res.status_code).to.equal('201')
            expect(res.body.applicant.status).to.equal('Pending')    
            }))
            
        })

In this case, I get a assert error embedded with the request and response along with some other stuff which I am unable to understand. The complete error goes something like this... "expected The following error originated from your test code, not from Cypress.\n\n > A response callback passed to req.reply() threw an error while intercepting a response:\n\nexpected undefined to equal '201'\n\nRoute: {\n "matchUrlAgainstPath": true,\n "url": "/hr/v1/applications/invite"\n}\n\nIntercepted request:{} Intercepted response: {} When Cypress detects uncaught errors originating from your test code it will automatically fail the current test. to include window.zE is not a function"

Its a bit weird to read this..

enter image description here

My application sometimes throws this exception, which I have handled using following code.

cy.on('uncaught:exception', (err, runnable) => {
            expect(err.message).to.include('window.zE is not a function')
            done()
            return false
        })

I really hope I have explained everything here. Please, help a noob. Regards

1
which means, the whole response is an object - no it's an array of objects. Start with cy.log(interception.response) and work from into the data from there (probably console.log(interception.response) is better). - Richard Matsen
Thanks Richard! As per your suggestion, Initially I tried only (interception.response)...Checked the output in the console..got an idea of how it looks... And modified the json traverse ... interception.response.body[0].body.applicant.URL - MeBhiAutomationTester

1 Answers

2
votes

As Richard Matsen suggested in the comments, I used console.log(interception.response) and checked the console output in the browser controlled by Cypress. I Noticed that the response json structure was something different than what I got in the network tab of developers tools, while using the web app. The response was something like below...

{headers: {…}, url: "https://example.com/hr/v1/applications/invite/batch/", method: null, httpVersion: "1.1", statusCode: 200, …}
   body: Array(1)
     0:
       body:
          applicant: {id: "c6b2d686-d4f3-483e-abc8-e4641c365845", status: "Pending", first_name: "", last_name: "", email: "[email protected]", …}
applicant_status: "NONE"
applicant_status_label: "None"
created: "2021-01-29T00:00:00Z"
get_applicant_status_display: "None"
id: "ad2939f5-c8ab-490a-a9e1-b0474de69e2c"
URL: "some url"

This made me modify the json traverse to interception.response.body[0].body.applicant.URL

If others have a neat way to handle this, please let me know!