Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Automatically include CORS headers for network stubbing #9264

Closed
flotwig opened this issue Nov 20, 2020 · 4 comments · Fixed by #9384
Closed

Automatically include CORS headers for network stubbing #9264

flotwig opened this issue Nov 20, 2020 · 4 comments · Fixed by #9384
Assignees
Labels
topic: cy.intercept() type: enhancement Requested enhancement of existing feature

Comments

@flotwig
Copy link
Contributor

flotwig commented Nov 20, 2020

What would you like?

Currently, users must specify CORS headers manually, if needed:

cypress-io/cypress-realworld-app@2df6ef7

    // Before: cy.route("GET", "/bankAccounts", []).as("getBankAccounts");
    cy.intercept(
      { method: "GET", url: "/bankAccounts" },
      {
        // TODO: automatically handle applying these headers
        headers: {
          "access-control-allow-origin": window.location.origin,
          "Access-Control-Allow-Credentials": "true",
        },
        body: { results: [] },
      }
    ).as("getBankAccounts");

This is some manual work that could probably be avoided in 99% of cases.

We should set Access-Control-Allow-Origin: ${request's origin header} and Access-Control-Allow-Credentials: true by default on stubbed responses so users don't need to do this manually.

@jennifer-shehane
Copy link
Member

I ran into this issue trying to convert cy.route() to cy.intercept() in the docs. Was opening a new issue when I saw this.

Current behavior

Trying to stub a request converting cy.route() to cy.intercept() causing some unexpected behavior. Maybe I'm doing this wrong, I haven't worked with cy.intercept() that much before, but the error states don't hint at what I'm doing wrong anyway.

Test code to reproduce

  1. ✅ Using cy.route() trying to pass an object to stub the response:
it('Displays Algolia dropdown on focus after close all banners', function () {
  cy.visit('https://docs.cypress.io/guides/overview/why-cypress.html')

  cy.server()

  cy.route({
    method: 'POST',
    url: /algolia/,
    response: {
      'results': [
        {
          'hits': [
            {
              'hierarchy': { 'lvl2': null, 'lvl3': null, 'lvl0': 'Known Issues', 'lvl1': null, 'lvl6': null, 'lvl4': null, 'lvl5': null },
              'url': 'https://docs-staging.cypress.io/guides/appendices/known-issues.html#content-inner', 'content': 'cy.get', 'anchor': 'content-inner', 'objectID': '15872310', '_snippetResult': { 'content': { 'value': 'to implement in Cypress.  Right <span class="algolia-docsearch-suggestion--highlight">click Issue #53</span>  Workaround  Oftentimes', 'matchLevel': 'full' } }, '_highlightResult': { 'hierarchy': { 'lvl0': { 'value': 'Known Issues', 'matchLevel': 'none', 'matchedWords': [] } }, 'content': { 'value': 'cy.get', 'matchLevel': 'full', 'fullyHighlighted': false, 'matchedWords': ['click', 'issue', '53'] }, 'hierarchy_camel': [{ 'lvl0': { 'value': 'Known Issues', 'matchLevel': 'none', 'matchedWords': [] } }] },
            },
          ], 'nbHits': 1, 'page': 0, 'nbPages': 1, 'hitsPerPage': 5, 'processingTimeMS': 1, 'exhaustiveNbHits': true, 'query': '"click Issue #53" ', 'params': 'query=%22click%20Issue%20%2353%22%20&hitsPerPage=5', 'index': 'cypress',
        },
      ],
    },
  }).as('postAlgolia')

  cy.get('.ds-dropdown-menu').should('not.be.visible')
  cy.get('#search-input').type('g')
  cy.wait('@postAlgolia')
  cy.get('.ds-dropdown-menu').should('be.visible')
})

Screen Shot 2020-11-24 at 2 43 33 PM

  1. ❗️ Using cy.intercept() to pass the object for stubbing response. When I click on the XHR in the Command Log it prints this:
CypressError: The network request for this XHR could not be made. Check your console for the reason.

So then I see this in the console:

Access to XMLHttpRequest at 'https://r9kda5fmjb-dsn.algolia.net/1/indexes/*/queries?x-algolia-agent=Algolia%20for%20vanilla%20JavaScript%20(lite)%203.30.0%3Bdocsearch.js%202.6.3&x-algolia-application-id=R9KDA5FMJB&x-algolia-api-key=8e6c3119ee78db1ad10cd7bfb439d726' from origin 'https://docs.cypress.io' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

Screen Shot 2020-11-24 at 2 54 49 PM

it('Displays Algolia dropdown on focus after close all banners', function () {
  cy.visit('https://docs.cypress.io/guides/overview/why-cypress.html#In-a-nutshell')
  cy.intercept(/algolia/, {
    'results': [
      {
        'hits': [
          {
            'hierarchy': { 'lvl2': null, 'lvl3': null, 'lvl0': 'Known Issues', 'lvl1': null, 'lvl6': null, 'lvl4': null, 'lvl5': null },
            'url': 'https://docs-staging.cypress.io/guides/appendices/known-issues.html#content-inner', 'content': 'cy.get', 'anchor': 'content-inner', 'objectID': '15872310', '_snippetResult': { 'content': { 'value': 'to implement in Cypress.  Right <span class="algolia-docsearch-suggestion--highlight">click Issue #53</span>  Workaround  Oftentimes', 'matchLevel': 'full' } }, '_highlightResult': { 'hierarchy': { 'lvl0': { 'value': 'Known Issues', 'matchLevel': 'none', 'matchedWords': [] } }, 'content': { 'value': 'cy.get', 'matchLevel': 'full', 'fullyHighlighted': false, 'matchedWords': ['click', 'issue', '53'] }, 'hierarchy_camel': [{ 'lvl0': { 'value': 'Known Issues', 'matchLevel': 'none', 'matchedWords': [] } }] },
          },
        ], 'nbHits': 1, 'page': 0, 'nbPages': 1, 'hitsPerPage': 5, 'processingTimeMS': 1, 'exhaustiveNbHits': true, 'query': '"click Issue #53" ', 'params': 'query=%22click%20Issue%20%2353%22%20&hitsPerPage=5', 'index': 'cypress',
      },
    ],
  }).as('postAlgolia')

  cy.get('.ds-dropdown-menu').should('not.be.visible')
  cy.get('#search-input').type('g')
  cy.wait('@postAlgolia')
  cy.get('.ds-dropdown-menu').should('be.visible')
})

Screen Shot 2020-11-24 at 2 44 55 PM

Workarounds

  1. Passing chromeWebSecurity: false does resolve this issue, but I never needed to do this before with cy.route() and this won't work in Firefox.

Screen Shot 2020-11-24 at 2 56 45 PM

  1. Passing access-control-allow-origi headers resolves it
  it('Displays Algolia dropdown on focus after close all banners', function () {
    cy.visit('https://docs.cypress.io/guides/overview/why-cypress.html#In-a-nutshell')
    cy.intercept(/algolia/, {
      body:{
        'results': [
          {
            'hits': [
              {
                'hierarchy': { 'lvl2': null, 'lvl3': null, 'lvl0': 'Known Issues', 'lvl1': null, 'lvl6': null, 'lvl4': null, 'lvl5': null },
                'url': 'https://docs-staging.cypress.io/guides/appendices/known-issues.html#content-inner', 'content': 'cy.get', 'anchor': 'content-inner', 'objectID': '15872310', '_snippetResult': { 'content': { 'value': 'to implement in Cypress.  Right <span class="algolia-docsearch-suggestion--highlight">click Issue #53</span>  Workaround  Oftentimes', 'matchLevel': 'full' } }, '_highlightResult': { 'hierarchy': { 'lvl0': { 'value': 'Known Issues', 'matchLevel': 'none', 'matchedWords': [] } }, 'content': { 'value': 'cy.get', 'matchLevel': 'full', 'fullyHighlighted': false, 'matchedWords': ['click', 'issue', '53'] }, 'hierarchy_camel': [{ 'lvl0': { 'value': 'Known Issues', 'matchLevel': 'none', 'matchedWords': [] } }] },
              },
            ], 'nbHits': 1, 'page': 0, 'nbPages': 1, 'hitsPerPage': 5, 'processingTimeMS': 1, 'exhaustiveNbHits': true, 'query': '"click Issue #53" ', 'params': 'query=%22click%20Issue%20%2353%22%20&hitsPerPage=5', 'index': 'cypress',
          },
        ],
    },
      headers: {
        "access-control-allow-origin": window.location.origin,
        "Access-Control-Allow-Credentials": "true",
      },}).as('postAlgolia')
    cy.get('.ds-dropdown-menu').should('not.be.visible')
    cy.get('#search-input').type('g')
    cy.wait('@postAlgolia')
    cy.get('.ds-dropdown-menu').should('be.visible')
  })

@cypress-bot cypress-bot bot added the stage: ready for work The issue is reproducible and in scope label Nov 24, 2020
@jonasraoni
Copy link

@jennifer-shehane, I've reached the same solution, but it doesn't work for me when I try to use the version with a handler function (I need custom responses).

Another difference is that my request has a custom header + withCredentials.
The OPTIONS request works, then the next request stays in a pending state forever.

I'll revert my tests to the server/route combo until it works and also the #9302 :)

@cypress-bot
Copy link
Contributor

cypress-bot bot commented Dec 2, 2020

The code for this is done in cypress-io/cypress#9384, but has yet to be released.
We'll update this issue and reference the changelog when it's released.

@cypress-bot cypress-bot bot removed the stage: needs review The PR code is done & tested, needs review label Dec 2, 2020
@cypress-bot
Copy link
Contributor

cypress-bot bot commented Dec 7, 2020

Released in 6.1.0.

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

@cypress-bot cypress-bot bot locked as resolved and limited conversation to collaborators Dec 7, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
topic: cy.intercept() type: enhancement Requested enhancement of existing feature
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants