You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Cypress测试离线模式Service Workers?fetch异常如何解决?

Service Worker Cypress 测试问题解决建议

一、优先尝试Cypress环境内修复方案

1. 修复fetch被劫持问题

Cypress 默认会改写页面的fetch请求用于请求录制、断言,导致Service Worker无法正常拦截fetch。你需要在cypress.config.js中添加配置禁用该行为:

const { defineConfig } = require('cypress')
module.exports = defineConfig({
  e2e: {
    experimentalFetchPolyfill: false,
    experimentalModifyObstructiveThirdPartyCode: false,
    // 若测试地址非localhost,添加以下启动参数保证SW可正常注册
    chromeWebSecurity: false,
    args: ['--unsafely-treat-insecure-origin-as-secure=http://你的测试地址']
  }
})

2. 替换不可靠的硬等待逻辑

你当前使用wait(1000)等待SW注册,可能出现SW未完成激活、资源未完成缓存就切换离线的情况,替换为状态监听逻辑:

it('can load if sw registered and try to visit', () => {
  cy.visit(folder)
  cy.contains('#sw-status', 'SW not registered')
  cy.get('#register').click()
  // 等待SW注册完成的状态更新,替代硬等待
  cy.contains('#sw-status', 'SW registered', { timeout: 5000 })
  // 可选:等待SW缓存所有必要资源后再切离线
  cy.waitUntil(() => 
    cy.window().then(win => 
      win.navigator.serviceWorker.ready.then(() => true)
    )
  )

  Cypress.goOffline()
  Cypress.assertOffline()
  // 手动修正navigator.onLine返回值,解决浏览器表现不一致问题
  cy.window().then(win => {
    Object.defineProperty(win.navigator, 'onLine', {
      value: false,
      configurable: true
    })
  })

  cy.get('#fetch').click()
  cy.contains('#fetch-response', '200', { timeout: 3000 })
})

3. 确认离线模拟范围

Cypress的CDP离线模拟默认会拦截所有网络请求,若你的SW会请求部分非缓存的跨域资源,可在CDP配置中添加例外规则,或提前mock对应的跨域响应。

二、更换测试框架方案(若上述方案无效)

如果Cypress的hack成本过高,可选择对Service Worker兼容性更好的测试框架:

  • Playwright:原生支持多浏览器离线状态控制,不会改写页面原生fetch、SW逻辑,可直接通过browserContext.setOffline(true)切换离线状态,和真实浏览器行为完全一致,是SW测试的优先替代方案。
  • Web Test Runner:配合Puppeteer控制真实浏览器的离线状态,轻量无侵入,适合小型SW测试场景。

内容的提问来源于stack exchange,提问作者raultm

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 21:48:03