如何拦截window.location.href跳转并在Cypress中模拟登录?
解决Cypress中阻止OAuth跳转并模拟登录的问题
因为window.location.href触发的是浏览器页面导航,而非AJAX请求,所以cy.intercept无法拦截这类行为。你可以通过Mock window.location.href的赋值逻辑来阻止真实跳转,并模拟登录状态。
方法一:使用cy.stub拦截href赋值
在点击登录按钮前,提前Stub窗口对象的location.href,自定义跳转行为:
// 获取当前窗口并Stub href属性 cy.window().then(win => { cy.stub(win.location, 'href').callsFake(targetUrl => { // 判断是否是目标OAuth跳转地址 if (targetUrl.includes('/oauth')) { // 模拟登录:设置认证令牌到localStorage(根据你的项目实际存储方式调整) win.localStorage.setItem('auth_token', 'mock-valid-token') // 手动跳转到登录后的目标页面 win.location.href = '/dashboard' } else { // 非OAuth跳转保持原有逻辑 return targetUrl } }) }) // 点击登录按钮 cy.get('button').click() // 验证模拟登录是否生效 cy.window().its('localStorage.auth_token').should('eq', 'mock-valid-token') cy.url().should('include', '/dashboard')
方法二:在页面加载前重定义location.href
利用cy.on('window:before:load')在页面加载完成前就修改location.href的setter,确保拦截逻辑提前生效:
// 页面加载前注入拦截逻辑 cy.on('window:before:load', win => { // 保存原始的href属性描述符 const originalHrefDesc = Object.getOwnPropertyDescriptor(win.location, 'href') // 重定义href的setter Object.defineProperty(win.location, 'href', { set: function(targetUrl) { if (targetUrl.includes('/oauth')) { // 模拟登录流程:设置认证信息 win.localStorage.setItem('user_info', JSON.stringify({ id: 1, name: 'mock-user' })) // 跳转到登录后的页面 originalHrefDesc.set.call(this, '/home') } else { // 其他跳转按原始逻辑执行 originalHrefDesc.set.call(this, targetUrl) } }, get: function() { return originalHrefDesc.get.call(this) } }) }) // 访问登录页面 cy.visit('/login') // 触发登录按钮点击 cy.get('RaisedButton').click() // 验证登录状态 cy.window().its('localStorage.user_info').should('not.be.empty') cy.url().should('eq', `${Cypress.config().baseUrl}/home`)
关键说明
cy.intercept仅对XHR/fetch请求有效,无法拦截浏览器的页面导航行为,所以必须从修改window.location的行为入手。- 模拟登录的逻辑需要和你项目实际的认证机制匹配,比如有的项目用cookie存储令牌,就需要修改
document.cookie而非localStorage。
内容的提问来源于stack exchange,提问作者alilland
相关产品推荐
相关产品推荐

