Cypress中如何正确断言表单提交GET请求的query参数
Cypress拦截搜索请求丢失查询参数修复方案
问题原因
你遇到的问题由两个核心错误导致:
cy.intercept的glob匹配规则写错:规则里的?是glob语法的特殊通配符,代表匹配任意单个字符,不是URL里字面量的问号,你写的/api/v1/foo/?include=**匹配逻辑完全不符合预期,会误捕获其他同路径请求。- 直接
cy.wait('@myRequest')默认会拿到第一个匹配拦截规则的请求,你捕获到的不带filter[number]参数的请求,是页面加载阶段提前触发的同路径接口,根本不是点击搜索按钮后发起的那一次搜索请求,自然拿不到搜索参数,interception.request.query为undefined也是因为匹配到了错误的请求,加上部分Cypress版本本身不会自动填充这个属性。
修复方法
1. 修正拦截规则
不要在拦截路径里硬拼查询参数,避免glob特殊字符导致匹配错误,优先用路径匹配或者正则匹配覆盖所有同路径请求:
// 推荐:用正则匹配接口路径,完全规避glob特殊字符问题 cy.intercept('GET', /\/api\/v1\/foo\//).as('fooApi');
如果需要精准只捕获带搜索参数的请求,可以直接在拦截回调里过滤,给目标请求单独打别名,后续wait的时候不会拿到错的请求:
cy.intercept('GET', /\/api\/v1\/foo\//, (req) => { if (req.url.includes('filter[number]=')) { req.alias = 'searchRequest' } })
2. 正确等待并断言请求参数
如果用了上面单独打别名的方式,直接等待对应别名即可,拿到请求后不要依赖Cypress自带的query属性,用原生URL对象解析查询参数兼容性最好:
cy.get('[data-cy="number"]').type('12345'); cy.get('[data-cy="search"]').click(); cy.wait('@searchRequest').then((interception) => { console.log('完整请求URL:', interception.request.url); // 直接断言URL包含目标参数 expect(interception.request.url).to.include('filter[number]=12345'); // 或者解析后精准断言参数值 const requestUrl = new URL(interception.request.url); const numberValue = requestUrl.searchParams.get('filter[number]'); expect(numberValue).to.eq('12345'); })
如果你不想在拦截回调里过滤,也可以在wait阶段循环判断,直到拿到带搜索参数的目标请求:
const getSearchRequest = () => { return cy.wait('@fooApi').then(interception => { if (interception.request.url.includes('filter[number]=12345')) { return interception } return getSearchRequest() }) } getSearchRequest().then(interception => { // 断言逻辑同上 })
注意:不要依赖
interception.request.query做参数断言,这个属性在Cypress 9.x之前的版本存在填充bug,且只有当拦截规则明确匹配对应查询参数时才会生成,手动用原生URL API解析是最稳定的方案。
内容的提问来源于stack exchange,提问作者Damon
相关产品推荐
相关产品推荐

