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

在Cypress中访问SVG的contentDocument时遇到问题

解决Cypress测试中Object元素加载SVG时contentDocument为null的问题

问题背景

在Chrome浏览器中应用运行完全正常,但使用Cypress执行基础测试(仅访问localhost:3000)时,页面加载阶段抛出以下错误:

Uncaught TypeError: Cannot read properties of null (reading 'querySelector')
    at ui.js:203:19
    at i ((index):4:1616)
    at (index):4:1989

经定位,问题出在SVG初始化函数svgMapLoaded中,Cypress环境下contentDocument返回null,但正常浏览器中能正确获取:

export function svgMapLoaded() {
  //-------------GLOBAL SVG CONSTANTS AFTER SVG LOADED---------------//
  svg = document.getElementById('svg-map');
  svgMap = document.getElementById('svg-map').contentDocument; // <-- Cypress中此处为null
  svgTag = svgMap.querySelector('svg');
  paths = Array.from(svgMap.querySelectorAll('path'));
//函数剩余部分
}

其中#svg-map是加载SVG的<object>元素:

<object id="svg-map" data="resources/svgMaster.svg" type="image/svg+xml" tabindex="0"></object>

该函数通过<object>的load事件触发执行:

<script type="module">
import { svgMapLoaded } from "./ui.js";
const svg = document.getElementById("svg-map");
svg.addEventListener("load", () => {
    svgMapLoaded();
});
</script>

手动添加1秒超时后问题仍存在,需要通过Cypress配置或代码调整解决。

解决方案

1. 修改Cypress核心配置

Cypress默认的安全策略会限制object/iframe内的跨域资源加载,在cypress.config.js中添加以下配置:

const { defineConfig } = require("cypress");

module.exports = defineConfig({
  e2e: {
    // 禁用Chrome的同源安全策略,允许加载本地SVG资源
    chromeWebSecurity: false,
    // 延长页面加载超时,给SVG足够的加载时间
    pageLoadTimeout: 10000,
    setupNodeEvents(on, config) {
      // 针对Chromium浏览器追加启动参数,进一步放宽资源限制
      on('before:browser:launch', (browser, launchOptions) => {
        if (browser.family === 'chromium' && browser.name !== 'electron') {
          launchOptions.args.push('--disable-web-security');
          launchOptions.args.push('--allow-file-access-from-files');
          return launchOptions;
        }
      });
    },
  },
});

2. 优化SVG初始化逻辑

不要仅依赖load事件,添加对contentDocument的有效性检查与重试机制:

export function svgMapLoaded() {
  svg = document.getElementById('svg-map');
  
  const initSvg = () => {
    svgMap = svg.contentDocument;
    // 确认contentDocument存在且包含SVG根元素
    if (svgMap && svgMap.querySelector('svg')) {
      svgTag = svgMap.querySelector('svg');
      paths = Array.from(svgMap.querySelectorAll('path'));
      // 执行后续业务逻辑
    } else {
      // 100ms后重试,最多重试20次(可根据实际情况调整)
      setTimeout(initSvg, 100);
    }
  };

  initSvg();
}

3. 在测试用例中显式等待SVG就绪

在Cypress测试中添加等待逻辑,确保SVG加载完成后再执行后续断言:

it('页面加载完成并成功初始化SVG', () => {
  cy.visit('localhost:3000');
  
  // 等待object的contentDocument不为null
  cy.get('#svg-map').then($obj => {
    return cy.wrap($obj[0].contentDocument).should('not.be.null');
  });
  
  // 或者直接等待SVG内的path元素出现(更直观)
  cy.get('#svg-map').its('0.contentDocument').find('path').should('exist');
});

4. 验证SVG资源路径正确性

确保Cypress运行时能正确访问SVG文件,可在测试开头添加资源验证:

cy.request('resources/svgMaster.svg').its('status').should('eq', 200);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 00:52:41