最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Cypress 7.0+Override responses in intercept - Stack Overflow

programmeradmin6浏览0评论

I hope you're doing well. I'm currently working on the upgrade of cypress to 7.0. (v7.4.0 more exactly) I have an issue with the overriding of intercept calls.

It seems that Cypress team worked on the overriding problem (issue : ), but it doesn't work for me.

BREAKING CHANGE: Request handlers supplied to cy.intercept are now matched starting with the most-recently-defined request interceptor. This allows users to override request handlers by calling cy.intercept again. This matches the previous behavior that was standard in cy.route.

My first call deals with 2xx responses (I mock it myself)

cy.intercept('GET', 'sameUrl', {
statusCode: 2xx
}

but then I need another intercept with the same url but a different status :

cy.intercept('GET', 'sameUrl', {
statusCode: 4xx
}

I tried using middleware : A new option, middleware, has been added to the RouteMatcher type. If true, the supplied request handler will be called before any non-middleware request handlers.

cy.intercept({ method: 'GET', url: 'sameUrl', middleware: true}, req => {
    req.continue(res => {
         res.statusCode = 4xx
    });
}

But it didn't work, the first intercept is always the one being called. Please if you have any idea what I did wrong/another solution I'm all ears !

I hope you're doing well. I'm currently working on the upgrade of cypress to 7.0. (v7.4.0 more exactly) I have an issue with the overriding of intercept calls.

It seems that Cypress team worked on the overriding problem https://github./cypress-io/cypress/pull/14543 (issue : https://github./cypress-io/cypress/issues/9302), but it doesn't work for me.

BREAKING CHANGE: Request handlers supplied to cy.intercept are now matched starting with the most-recently-defined request interceptor. This allows users to override request handlers by calling cy.intercept again. This matches the previous behavior that was standard in cy.route.

My first call deals with 2xx responses (I mock it myself)

cy.intercept('GET', 'sameUrl', {
statusCode: 2xx
}

but then I need another intercept with the same url but a different status :

cy.intercept('GET', 'sameUrl', {
statusCode: 4xx
}

I tried using middleware : A new option, middleware, has been added to the RouteMatcher type. If true, the supplied request handler will be called before any non-middleware request handlers.

cy.intercept({ method: 'GET', url: 'sameUrl', middleware: true}, req => {
    req.continue(res => {
         res.statusCode = 4xx
    });
}

But it didn't work, the first intercept is always the one being called. Please if you have any idea what I did wrong/another solution I'm all ears !

Share Improve this question edited Jun 7, 2021 at 13:45 user9622173 asked Jun 7, 2021 at 10:52 Fujo DJFujo DJ 731 silver badge5 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 5

If I make a minimal example app + test, it follows the rules you quoted above.

Test

it('overrides the intercept stub', () => {

  cy.visit('../app/intercept-override.html')
  
  cy.intercept('GET', 'someUrl', { statusCode: 200 })

  cy.get('button').click()

  cy.get('div')
    .invoke('text')
    .should('eq', '200')                               // passes

  cy.intercept('GET', 'someUrl', { statusCode: 404 })

  cy.get('button').click()

  cy.get('div')
    .invoke('text')
    .should('eq', '404')                               // passes
})

App

<button onclick="clicked()">Click</button>
<div>Result</div>
<script>
  function clicked() {
    fetch('someUrl').then(response => {
      const div = document.querySelector('div')
      div.innerText = response.status
    })
  }
</script>

So, what's different in your app?


Test revised according to ments

Main points that break the test

  • unique aliases are needed
  • the string-based url (2nd test) requires minimatch wildcard prefix ** to work
beforeEach(() => {
  cy.intercept('GET', /api\/test-id\/\d+/, { statusCode: 200 })
    .as('myalias1')
  cy.visit('../app/intercept-overide.html')
})

it('sees the intercept stub status 200', () => {
  cy.get('button').click()
  cy.wait('@myalias1')
  cy.get('div')
    .invoke('text')
    .should('eq', '200')
})

it('sees the intercept stub status 404', () => {
  cy.intercept('GET', '**/api/test-id/1', { statusCode: 404 })
    .as('myalias2')

  cy.get('button').click()
  cy.wait('@myalias2')
  cy.get('div')
    .invoke('text')
    .should('eq', '404')
})

App

<button onclick="clicked()">Click</button>
<div>Result</div>
<script>
  function clicked() {
    fetch('/api/test-id/1').then(response => { 
      // logs as "http://localhost:53845/api/test-id/1" in the Cypress test runner
      const div = document.querySelector('div')
      div.innerText = response.status
    })
  }
</script>

Minimatch

The 2nd intercept uses a string which will match using minimatch. Use this code to check the intercept will work with your app's URL

Cypress.minimatch(<full-url-from-app>, <url-in-intercept>)  // true if matching 
发布评论

评论列表(0)

  1. 暂无评论