Chrome 100+环境下如何在Cypress中修改userAgent模拟移动端?
Chrome 100+ 环境下Cypress修改UserAgent的可行方案
Chrome 100版本后,navigator.userAgent被标记为不可配置的原生属性,原先在cy.visit的onBeforeLoad钩子中通过Object.defineProperty重写属性的方式已经失效,强行调用要么抛出JS错误,要么修改后的值无法被业务代码正常读取。
目前有两种稳定的可编程方案,均可以实现真实模拟UA的需求,不会被浏览器安全策略拦截:
- 方案1:通过Cypress原生配置修改(适合固定UA场景)
Cypress原生支持在浏览器启动阶段直接设置UA,该配置会同时生效于网络请求头与navigator.userAgent属性,完全符合真实访问逻辑。
全局配置方式(所有用例默认使用该UA),在cypress.config.js中添加如下配置:
如果需要针对单个测试用例/测试集临时修改UA,可以在用例执行前动态修改配置,再重载页面即可生效。const { defineConfig } = require("cypress"); module.exports = defineConfig({ e2e: { userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.0 Mobile/14E304 Safari/602.1' } }); - 方案2:通过CDP协议动态修改(适合多UA切换场景)
如果需要在测试过程中动态切换不同UA(比如同一个用例里先后模拟安卓、iOS、桌面端),可以调用Cypress封装的Chrome DevTools Protocol接口直接修改浏览器底层UA配置,该方式优先级高于页面属性,不会被Chrome拦截,还可以同步模拟移动端设备特征。
示例代码如下:
这个方案比单纯修改viewport更贴近真实移动设备环境,如果需要进一步模拟屏幕尺寸、触摸事件、设备像素比等参数,可以搭配it('模拟iOS Safari访问场景', () => { // 调用CDP接口覆写UA Cypress.automation('remote:debugger:protocol', { command: 'Network.setUserAgentOverride', params: { userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.0 Mobile/14E304 Safari/602.1', platform: 'iPhone', mobile: true // 标记为移动端,同步开启浏览器移动端相关特性 } }) // 访问目标页面,此时请求头、navigator.userAgent均为设置的iOS UA cy.visit('你的测试地址') // 可选:验证UA是否设置成功 cy.window().its('navigator.userAgent').should('include', 'iPhone') })Emulation.setDeviceMetricsOverride的CDP命令使用,不需要依赖Cypress的viewport模拟。
注意:不要继续尝试在页面上下文内重写
navigator相关属性,Chrome 100之后对这类客户端标识属性做了只读保护,页面层的修改要么不生效,要么会被部分JS读取逻辑绕过,导致测试结果不可靠。
内容的提问来源于stack exchange,提问作者Warrior1337
相关产品推荐
相关产品推荐

