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 badges1 Answer
Reset to default 5If 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