升级Testcafe至2.5.1-rc.1后请求Mock出现CORS问题求助
问题背景
将项目从Testcafe 1.2.1版本升级至2.5.1-rc.1后,原本运行正常的测试用例执行失败,报错如下:
1) Cannot obtain information about the node because the specified selector does not match any node in the DOM tree. > | Selector('.review__title') | .nth(0)
进一步排查发现,选择器查找失败的根源是组件未渲染,而组件未渲染是因为请求触发了CORS错误:
Access to fetch at 'http://192...' from origin 'http://192...' has been blocked by CORS policy: Request header field content-encoding is not allowed by Access-Control-Allow-Headers in preflight response.
升级后出现问题的原因
Testcafe 2.x版本对请求拦截机制做了调整,核心变化点:
- 1.x版本中,Testcafe不会自动在模拟请求中添加
content-encoding这类额外请求头,浏览器对Mock请求的CORS校验也相对宽松; - 2.x版本升级了内部请求处理逻辑,会自动携带
content-encoding等头信息,而现有请求Mock仅设置了access-control-allow-origin: *,未将content-encoding纳入Access-Control-Allow-Headers允许列表,导致浏览器预检请求(OPTIONS)失败,真实请求被拦截,组件因无数据而不渲染。
另外,getProductsBySeoUrlMock的URL匹配规则存在误匹配风险:
url.includes(`/reviews`) && method === "get"
该规则会拦截所有包含/reviews的GET请求,可能抢占fetchReviewsMock的处理优先级,且它的响应头同样缺少必要的CORS配置,进一步加剧问题。
解决方法
1. 完善所有请求Mock的CORS响应头
在所有RequestMock的respond方法中,补充完整的CORS允许头,确保包含content-encoding:
// 示例:更新fetchReviewsMock的响应头 export const fetchReviewsMock = RequestMock() .onRequestTo(isFetchReviews) .respond( { Locale: "en_US", Includes: {}, Errors: [], Results: [ { UserNickname: "Tester", Rating: 4, ReviewText: "Terrible product", }, ], TotalResults: 16, Limit: 10, HasErrors: false, Offset: 0, }, 200, { "access-control-allow-origin": "*", "access-control-allow-headers": "content-encoding, content-type", "access-control-allow-methods": "GET, OPTIONS" } );
同理更新submitInappropriateFeedbackMock和getProductsBySeoUrlMock的响应头,覆盖所有必要的CORS配置项。
2. 修正请求Mock的URL匹配规则
调整getProductsBySeoUrlMock的匹配逻辑,避免误拦截其他请求:
export function getProductsBySeoUrlMock(seoUrl: string, resBody: object = response) { return RequestMock() .onRequestTo( ({ url, method }: RequestData) => // 结合seoUrl参数做精准匹配 url.includes(`/products/${seoUrl}/reviews`) && method === "get" ) .respond(resBody, 200, { "access-control-allow-origin": "*", "access-control-allow-headers": "content-encoding, content-type", "access-control-allow-methods": "GET, OPTIONS" }); }
确保每个Mock仅处理对应的目标请求,避免拦截冲突。
3. 优化测试流程中的导航逻辑
Fixture中同时设置了.page(startUrl)和beforeEach内的navigateTo(startUrl),重复导航可能打乱请求加载顺序,可移除其中一个:
fixture("Product Details Reviews") .requestHooks(...defaultMocks, getCategoriesTreeMock, getCustomerProfileMock) .page(startUrl); // 移除重复的beforeEach导航逻辑
4. 临时绕过CORS校验(仅测试环境)
若上述配置无法快速生效,可在Testcafe启动命令中添加--disable-web-security参数禁用浏览器同源策略:
testcafe chrome tests/ --disable-web-security
注意:这是临时方案,仅用于测试环境,生产环境禁止使用。
验证步骤
- 应用修改后重新运行测试;
- 启动测试时添加
--devtools参数,打开浏览器开发者工具检查请求:- 确认OPTIONS预检请求返回200;
- 确认
/data/reviews.json等请求能正常获取Mock数据;
- 验证组件正常渲染,选择器能找到
.review__title节点。
内容的提问来源于stack exchange,提问作者Dan

