如何解决Cypress中等待指定GraphQL请求完成不生效的问题
Cypress 等待指定GraphQL请求失效的解决方案
失效原因
- 匹配逻辑有盲区:原代码仅校验
req.body.id字段,未覆盖标准GraphQL规范中存储查询名的req.body.operationName字段。一旦实际请求的查询名挂载在operationName下,别名根本不会被绑定,cy.wait自然匹配不到目标请求。 - 时序错位:本地开发环境的GraphQL请求通常是毫秒级返回,当代码执行到
cy.wait('@TakedownUserRendererQuery')时,点击请求行触发的目标请求已经走完完整生命周期,没有留在Cypress的别名等待队列中,此时wait会一直等下一次同别名的请求,直到超时。 - 等待覆盖不全:后续点击编辑、取消、重新点击编辑的操作,都会重新触发目标GraphQL请求拉取页面数据。原代码仅在第一次点击请求行后做了等待,后续操作触发的请求没有被等待,容易出现元素未渲染完成就执行交互的问题。
修正代码
优先用稳定的方式绑定别名,同时覆盖所有需要等待的操作节点:
describe('CopyrightModule', () => { it('edit, cancel, edit, save', () => { // 注册拦截器,兼容两种常见的GraphQL查询名存储位置,稳定绑定别名 cy.intercept('POST', '/graphql', (req) => { const queryName = req.body.id || req.body.operationName if (queryName === 'TakedownUserRendererQuery') { req.alias = 'TakedownUserRendererQuery' } }) cy.visit('/') cy.get(selectors.DMCA_LINK).click({ force: true }) cy.contains('My Requests').click() // 点击请求行触发目标查询,点击后等待请求完成 cy.get(selectors.REQUEST_ROW) .first() .click() cy.wait('@TakedownUserRendererQuery') cy.get(selectors.COPYRIGHT_EDIT).click() cy.contains('Cancel').click() // 重新点击编辑按钮同样会触发目标查询,补充等待逻辑 cy.get(selectors.COPYRIGHT_EDIT).click() cy.wait('@TakedownUserRendererQuery') // 等待数据渲染完成后再执行输入操作 cy.contains('div', 'Owner Website URLs') .find('input') .first() .type('8000-1612023') }) })
稳定性优化
如果测试环境请求速度极快,还是偶现等待超时,可以直接用Cypress静态请求匹配的方式绑定别名,跳过动态回调判断的流程,从根源上减少时序偏差:
// 静态匹配目标请求,直接绑定别名 cy.intercept({ method: 'POST', url: '/graphql', // 根据实际请求的字段选择匹配id或者operationName body: { operationName: 'TakedownUserRendererQuery' } }).as('TakedownUserRendererQuery')
这种写法是Cypress在网络层直接完成请求匹配,不需要执行回调逻辑再绑定别名,稳定性远高于动态回调设置别名的方式。
内容的提问来源于stack exchange,提问作者Batman
相关产品推荐
相关产品推荐

