question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Yield object instead of string in cy.wait when request content-type is valid JSON Mime type (not only application/json)

See original GitHub issue

Possibly a duplicate or related to https://github.com/cypress-io/cypress/issues/14273.

Our back-end services use JSON:API spec (https://jsonapi.org/) which recommends the media type application/vnd.api+json. They deliver valid JSON in the response body, which should be converted to an object by cy.wait to allow for deep assertions.

Current behavior

If request is intercepted with cy.intercept(), then cy.wait() yields a string for the response body (related issue: #14273.)

From this comment: https://github.com/cypress-io/cypress/issues/14273#issuecomment-765625317, I believe this is due to the check in https://github.com/cypress-io/cypress/blob/6ee7a9c27e9ea8b7dceee6bae140ce86d816a5e1/packages/driver/src/cy/net-stubbing/events/utils.ts#L4-L20

Due to our back-end sending content-type: application/vnd.api+json this check fails, and so the response body is not converted using JSON.parse.

Desired behavior

I believe that if the response to a request is valid JSON, it should be converted to a JS object regardless of the headers. This approach is taken elsewhere in Cypress, ie: https://github.com/cypress-io/cypress/blob/dae76a8ec0a149d5f4ca4fbe4d15bea1b5f7449d/packages/server/lib/controllers/xhrs.js#L9-L23

Effectively if JSON.parse(text) succeeds without throwing, we can assume that text is valid JSON and return the resulting parsed object.

Test code to reproduce

describe('cy.intercept tests', () => {
  it('test cy.intercept() with application/json', () => {
    cy.intercept('POST', '/users', { foo: 'bar' }).as('postUrl');
    cy.visit('https://example.com');
    cy.then((win) => {
      Cypress.$.ajax({
        url: '/users',
        method: 'POST',
        contentType: 'application/json',
        data: JSON.stringify({ name: 'XYZ' }),
      });
    });

    cy.wait('@postUrl')
      .should((interception) => {
        expect(typeof interception.response.body).to.eq('object');
        expect(interception.response.body).to.deep.eq({ foo: 'bar' })
      });
  });

  it('test cy.intercept() with application/vnd.api+json', () => {
    // temporary API endpoint at mocky.io that responds with 'content-type: application/vnd.api+json'
    cy.intercept('GET', 'https://run.mocky.io/v3/5c528eae-f3c0-4dbe-b9cb-7b12a00320ad').as('jsonApiUrl');
    cy.visit('https://example.com');
    cy.then((win) => {
      Cypress.$.ajax({
        url: 'https://run.mocky.io/v3/5c528eae-f3c0-4dbe-b9cb-7b12a00320ad',
        method: 'GET',
      });
    });

    cy.wait('@jsonApiUrl')
      .should((interception) => {
        expect(interception.response.headers['content-type']).to.contain('application/vnd.api+json');
        // ❗️ fails
        expect(typeof interception.response.body).to.eq('object');
        // ❗️ fails
        expect(interception.response.body).to.deep.eq({ foo: 'bar' });
      });
  });
});

Versions

6.3.0

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:2
  • Comments:6 (3 by maintainers)

github_iconTop GitHub Comments

2reactions
aethrcommented, Jan 27, 2021

Good points. I did some testing and route in Cypress 5 and 6 are both consistent in not converting the response body to objects in this scenario, so my suggestion would probably be a breaking change for some.

A brief search on iana turned up a few likely JSON-compatible media types:

Most seem to follow the same pattern:

  • application/SOMETHING+json
  • application/vnd.SOMETHING+json

Perhaps the check could be expanded to:

return contentType && /^application\/.*json/i.test(contentType)
0reactions
cypress-bot[bot]commented, Apr 5, 2021

Released in 7.0.0.

This comment thread has been locked. If you are still experiencing this issue after upgrading to Cypress v7.0.0, please open a new issue.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Asserting Network Calls from Cypress Tests
setRequestHeader("Content-Type", "application/json ... The Cypress Test Runner automatically waits for cy.contains to find the given visible ...
Read more >
Cypress cy.intercept Problems - Gleb Bahmutov
Cached response #​​ Let's inspect the interception object yielded by the cy. wait command. We cannot validate the data sent by the server, ......
Read more >
Cypress - The Blue Book - GitHub Pages
Automatic Waiting: Never add waits or sleeps to your tests. Cypress automatically waits for commands and assertions before moving on. No more async...
Read more >
A Practical Guide to Intercepting Network Requests in Cypress
To target e.g. only our POST /api/boards request, we'll write our command like ... does not actually wait for our network request to...
Read more >
Network Requests 2 - cypress - w3resource
Whenever you start a cy.server() and define cy.route() commands, Cypress will display the routes under “Routes” in the Command Log. cypress: ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found