Cypress发送API请求时出现Promise错误,求解决方法
Cypress API请求Promise错误的解决方案及遗漏要点
核心问题分析
Cypress命令与原生Promise异步机制冲突
Cypress的命令(如cy.request)基于自身异步队列运行,而fetch是浏览器原生Promise,不会被Cypress队列跟踪。在cy.request的then块直接调用fetch时,Cypress无法等待fetch完成就继续执行后续逻辑,导致未处理的Promise错误。变量传递与全局变量的风险
使用全局变量woID存储工单编号,Cypress的异步执行顺序可能导致后续请求拿到初始值0;且第二个then块的参数out为undefined,因为前一个then未返回任何值,无法获取之前的响应数据。请求超时未配置
系统响应需60-70秒,但cy.request默认超时时间为30秒,直接导致请求超时失败,引发后续Promise错误。请求Body的JSON语法错误
手动拼接的body字符串存在语法问题:"statusList":"sortDirection":"DESC"缺少键值对分隔与正确结构,手动拼接JSON极易出现这类错误。
解决方案
1. 统一使用Cypress命令(推荐)
将fetch替换为cy.request,让所有异步请求加入Cypress命令队列,确保执行顺序与等待机制正常:
class utils { createWorkOrderViaAPI() { cy.request({ url: 'URL', method: 'POST', headers: { properties: 'wonum', 'Content-Type': 'application/json', MAXAUTH: 'autpassword', Authorization: 'Basic ' + 'autpassword' }, body: { description: 'test request', }, timeout: 80000 // 设置80秒超时,覆盖默认30秒 }).then((res) => { const woID = res.body.wonum; // 用局部变量替代全局变量 // 返回cy.request,让后续then等待请求完成 return cy.request({ url: 'https://URL', method: 'POST', headers: { accept: 'application/json, text/plain, */*', 'accept-language': 'tr-TR,tr;q=0.9,en-US;q=0.8,en;q=0.7', authorization: 'Bearer ' + keyCloakToken, }, body: { // 用对象自动生成正确JSON格式,避免手动拼接错误 statusList: [], // 根据实际接口调整结构 sortDirection: "DESC", archivalTypeList: ["ACTIVE"], countByField: "NEIGHBORHOOD", searchText: woID } }); }).then((res) => { const woCoordinate = res.body.wkt; cy.log(woCoordinate); // 若需后续使用该值,设置别名 cy.wrap(woCoordinate).as('woCoordinate'); }); } }
2. 若必须使用fetch,需包裹成Cypress可跟踪的Promise
如果因特殊需求必须使用fetch,需用cy.wrap包裹,让Cypress能跟踪并等待该Promise完成:
createWorkOrderViaAPI() { cy.request({ url: 'URL', method: 'POST', headers: { /* 原请求头 */ }, body: { /* 原请求体 */ }, timeout: 80000 }).then((res) => { const woID = res.body.wonum; // 用cy.wrap包裹fetch,纳入Cypress异步队列 return cy.wrap( fetch('https://URL', { headers: { /* 原fetch请求头 */ }, body: JSON.stringify({ // 用JSON.stringify生成正确JSON statusList: [], sortDirection: "DESC", archivalTypeList: ["ACTIVE"], countByField: "NEIGHBORHOOD", searchText: woID }), method: 'POST' }).then(res => res.json()) ); }).then((fetchRes) => { const woCoordinate = fetchRes.wkt; cy.log(woCoordinate); }); }
3. 其他注意事项
- 避免全局变量:Cypress异步模型下,全局变量易出现值未更新的问题,优先在
then链内传递变量,或用cy.as设置别名,后续通过cy.get('@alias')获取。 - 排查请求差异:将
cy.request换为fetch后无法创建工单,大概率是两者请求头/参数不一致(cy.request会自动处理部分Cookies或头信息),可通过浏览器开发者工具对比请求详情。 - 超时时间适配:针对慢响应接口,必须给
cy.request设置足够长的timeout参数(单位:毫秒)。
内容的提问来源于stack exchange,提问作者Barış Can Ateş
相关产品推荐
相关产品推荐

