使用Cypress拦截请求后页面未触发弹窗,是否阻塞程序流程?
场景说明
我在编写Cypress测试时,需要发起API请求并拦截响应。误以为无法通过cy.request()+cy.intercept()实现,于是尝试用fetch和cy.intercept组合的方式。
测试代码
const requestBody = 'XXXXX' apiUrl = 'XXXXX' cy.intercept('POST', 'apiUrl', {fixture: 'video.json'}) .as('user') .then(() => { fetch('apiUrl' , {method: 'POST', body: requestBody}) .then((r) => r.json()) .then((body) => { }) }) cy.wait('@user').its('response.body')
Fixture文件内容(video.json)
{ "data": { "currentUser": { "id": 99, "pending_sessions": [ { "id": "950", "patient": { "id": "106", "call9_location": { "id": 8, "name": "test", "abbreviation": "aa" }, "ot_session_id": "123", "ot_token": "ABC" }, "most_recent_caller": { "id": "9", "meta_type": "Technician", "first_name": "Test", "last_name": "Tester" } } ] } } }
问题现象
测试运行时,能看到API请求已发起且响应被成功拦截,返回了fixture中的正确数据,但按照应用逻辑,当响应的pending_sessions节点有内容时应该弹出的浏览器弹窗并未出现。想确认是不是Cypress的拦截机制阻塞了流程,或是我遗漏了关键步骤?
核心原因:请求上下文不匹配
你用fetch手动发起的请求,是在Cypress测试的上下文里执行的,并没有触发应用自身的请求处理逻辑——应用代码根本没接收到这个响应,自然不会触发弹窗。应用的弹窗逻辑应该是绑定在它自己发起的API请求的回调里,而非测试代码发起的请求。
解决方法
触发应用原生请求逻辑:不要手动用
fetch发请求,而是通过操作页面元素(比如点击按钮、触发对应事件)让应用自己发起这个POST请求。这样cy.intercept拦截到响应后,应用的代码会正常处理并触发弹窗。检查
cy.intercept的匹配规则:你的代码里cy.intercept('POST', 'apiUrl')中的apiUrl是字符串字面量,不是变量,应该改成cy.intercept('POST', apiUrl, {fixture: 'video.json'})(用变量而非字面量),否则可能拦截的是地址为apiUrl的无效请求(你说拦截成功可能是隐藏内容时的笔误,但务必确认)。等待应用逻辑执行完成:有些应用会在请求响应后做异步渲染,你可以在
cy.wait('@user')之后添加断言等待弹窗出现,比如:cy.wait('@user').its('response.body') cy.get('.modal-selector').should('be.visible') // 替换成你弹窗的选择器若需手动调用(不推荐):如果确实无法通过页面操作触发请求,直接调用应用暴露的请求方法,而非自己写
fetch。比如:cy.window().then(win => { win.appApi.fetchPendingSessions(requestBody) // 替换成应用实际的请求方法 })
内容的提问来源于stack exchange,提问作者bluesky1012

