Cypress 7.0+ / 在拦截中覆盖响应
Cypress 7.0+ / Override responses in intercept
希望你一切顺利。
我目前正在将 cypress 升级到 7.0. (更确切地说是 v7.4.0)
我对覆盖拦截调用有疑问。
Cypress 团队似乎解决了最重要的问题 https://github.com/cypress-io/cypress/pull/14543 (issue : https://github.com/cypress-io/cypress/issues/9302),但它对我不起作用。
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.
我的第一个电话处理 2xx 响应(我自己嘲笑)
cy.intercept('GET', 'sameUrl', {
statusCode: 2xx
}
但是我需要另一个具有相同 url 但不同状态的拦截:
cy.intercept('GET', 'sameUrl', {
statusCode: 4xx
}
我尝试使用 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
});
}
但是没有用,第一个拦截总是被调用。如果您知道我做了什么,请 wrong/another 解决方案我洗耳恭听!
如果我做一个最小的示例应用程序 + 测试,它会遵循您上面引用的规则。
测试
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
})
应用程序
<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>
那么,您的应用有何不同?
根据评论修改测试
破试要点
- 需要唯一的别名
- 基于字符串的 url(第二次测试)需要最小匹配通配符前缀
**
才能工作
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')
})
应用程序
<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>
小匹配
第二次截取使用一个字符串,该字符串将使用最小匹配进行匹配。使用此代码检查拦截是否适用于您应用的 URL
Cypress.minimatch(<full-url-from-app>, <url-in-intercept>) // true if matching
希望你一切顺利。 我目前正在将 cypress 升级到 7.0. (更确切地说是 v7.4.0) 我对覆盖拦截调用有疑问。
Cypress 团队似乎解决了最重要的问题 https://github.com/cypress-io/cypress/pull/14543 (issue : https://github.com/cypress-io/cypress/issues/9302),但它对我不起作用。
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.
我的第一个电话处理 2xx 响应(我自己嘲笑)
cy.intercept('GET', 'sameUrl', {
statusCode: 2xx
}
但是我需要另一个具有相同 url 但不同状态的拦截:
cy.intercept('GET', 'sameUrl', {
statusCode: 4xx
}
我尝试使用 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
});
}
但是没有用,第一个拦截总是被调用。如果您知道我做了什么,请 wrong/another 解决方案我洗耳恭听!
如果我做一个最小的示例应用程序 + 测试,它会遵循您上面引用的规则。
测试
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
})
应用程序
<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>
那么,您的应用有何不同?
根据评论修改测试
破试要点
- 需要唯一的别名
- 基于字符串的 url(第二次测试)需要最小匹配通配符前缀
**
才能工作
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')
})
应用程序
<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>
小匹配
第二次截取使用一个字符串,该字符串将使用最小匹配进行匹配。使用此代码检查拦截是否适用于您应用的 URL
Cypress.minimatch(<full-url-from-app>, <url-in-intercept>) // true if matching