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

Cypress测试Next.js预渲染React应用如何捕获hydration阶段加载屏?

解决方案

  • 调整查询配置,新增超时和隐藏元素捕获参数
    测试偶发失败的核心原因是双通渲染下,加载屏的存在窗口较短,Cypress默认4秒超时和忽略隐藏元素的规则可能刚好错过加载屏的捕获时机。给findByRole查询新增timeout参数延长等待窗口,添加includeHiddenElements: true配置捕获刚插入DOM还未移除隐藏属性的加载节点。
  • 增加加载屏消失的断言确保渲染阶段完成
    在完成加载屏的存在校验后,新增断言等待加载屏完全卸载,再执行后续表单操作,避免Cypress在渲染过渡阶段查询后续节点引发不稳定。
  • 非必要场景可跳过加载屏存在校验
    如果你的测试不需要验证加载屏是否正常渲染,可直接断言加载屏不存在,无需校验它的出现过程,彻底规避错过渲染窗口的问题。

调整后稳定的测试代码示例

// using @testing-library/cypress
it('Some of my tests', () => {
  cy.visit('http://localhost:4000/annotation/edit');
  // 捕获加载屏,调整配置避免漏捕
  cy.get('div#__next').findByRole('alert', { 
    name: /loading/i,
    timeout: 10000,
    includeHiddenElements: true
  });
  // 等待加载阶段完全结束
  cy.findByRole('alert', { name: /loading/i }).should('not.exist', { timeout: 10000 });

  cy.findByRole('form', { name: /sign in form/i }).within(() => {
    cy.findByRole('textbox', { name: /account name/i }).type('...');
    cy.findByRole('textbox', { name: /email/i }).type('...');
    cy.findByLabelText(/password/i).type('...');
    cy.findByRole('button', { name: /sign in/i }).click();
  });
  cy.findByRole('progressbar');
});

可选:直接获取当前DOM状态的方式

如果需要自行判断当前DOM的渲染状态,可以通过then回调获取挂载节点的DOM内容自行处理,不推荐常规场景使用,会引入条件测试的不稳定风险:

cy.get('div#__next').then($root => {
  const hasLoadingAlert = $root.find('[role="alert"][aria-label*="loading"]').length > 0;
  // 自行编写后续逻辑
});

不推荐使用固定时长的cy.wait()做节流控制,固定等待时间会拉长测试执行耗时,且无法适配不同环境下的渲染速度差异,依然可能出现偶发失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 07:12:00