如何在Cypress测试中正确拦截GraphQL响应并提取使用数据?
解决Cypress拦截GraphQL请求超时并提取OTP的问题
问题根源分析
- 拦截时机错误:你在点击登录按钮后才设置
cy.intercept,此时请求已经发送,Cypress来不及监听,必然触发超时。 - Intercept回调用法错误:
req.continue内嵌套req.reply属于冗余操作,req.continue本身就是用来处理响应的,无需重复调用req.reply。 - OTP存储方式不可靠:将OTP存在
req.otp中不如用Cypress环境变量或cy.wrap存储,后续步骤获取更稳定。
修正后的代码
describe('Login functionality', () => { it('should login successfully', () => { const email = 'admin@email.com'; const password = 'password'; // 1. 提前设置拦截,确保请求发送前已监听 cy.intercept('POST', 'http://localhost:3000/graphql', (req) => { // 匹配GraphQL的operationName,注意大小写需与实际请求一致 if (req.body.operationName === 'LoginVerify') { req.alias = 'loginVerify'; // 处理响应并提取OTP req.continue((res) => { // 确认响应结构,此处假设OTP位于res.body.data.getTestOtp const testOtp = res.body.data.getTestOtp; // 将OTP存入Cypress环境变量,方便后续调用 Cypress.env('testOtp', testOtp); }); } }); // 2. 执行登录前置操作 cy.visit('/'); cy.get('input[type="email"]').type(email).should('have.value', email); cy.get('input[type="password"]').type(password); cy.get('[data-cy="submit-btn"]').click(); // 3. 等待拦截到目标请求 cy.wait('@loginVerify').then(() => { // 从环境变量获取OTP const testOtp = Cypress.env('testOtp'); // 4. 使用OTP完成登录流程 cy.get('input[type="number"]').type(testOtp).should('have.value', testOtp); cy.get('[data-cy="submit-btn"]').click(); // 用断言替代固定等待,Cypress会自动等待元素出现 cy.contains('Welcome Admin'); }); }); });
额外调试建议
- 检查浏览器Network面板,确认GraphQL请求的
operationName是否与代码中完全一致(注意大小写)。 - 如果operationName匹配不稳定,可改用请求体中的query关键字匹配:
if (req.body.query.includes('getTestOtp')) { req.alias = 'loginVerify'; // 后续处理逻辑 } - 避免使用
cy.wait(100)这类固定等待,优先用Cypress的断言自动等待机制,提升测试稳定性。
内容的提问来源于stack exchange,提问作者user12504353
相关产品推荐
相关产品推荐

