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

如何在Cypress.io中模拟窗口失去焦点?

解决Cypress中触发窗口失焦以验证Angular Material对话框的问题

我之前也碰到过类似的场景,Angular Material的焦点检测对话框在Cypress测试里确实不太好直接触发,不过有几个经过验证的方法可以帮你解决这个问题:

方法1:直接触发窗口blur事件

这是最直接的方式,通过Cypress获取当前窗口对象,然后触发原生的blur事件:

cy.window().trigger('blur');

不过要注意,在某些情况下(比如headless模式),这个事件可能不会被应用正确识别,因为Cypress的测试上下文和浏览器窗口的实际焦点状态有差异。

方法2:模拟visibilitychange事件

很多现代应用(包括Angular Material)会监听visibilitychange事件来判断窗口是否失去焦点(比如用户切换标签页),你可以模拟文档变为隐藏状态并触发这个事件:

cy.window().then(win => {
  // 模拟文档处于隐藏状态(窗口失焦)
  Object.defineProperty(win.document, 'hidden', { value: true });
  // 触发visibilitychange事件
  win.dispatchEvent(new Event('visibilitychange'));
});

这个方法通常比单纯触发blur更可靠,因为它更贴近用户实际切换窗口的行为。

方法3:修改document.hasFocus()的返回值

如果你的应用或Angular Material组件直接调用document.hasFocus()来判断焦点状态,可以用Cypress的stub来修改这个方法的返回值:

cy.window().then(win => {
  cy.stub(win.document, 'hasFocus').returns(false);
  // 触发组件的焦点检测逻辑,或者直接触发相关事件
  win.dispatchEvent(new Event('blur'));
});

完整测试示例

结合上面的方法,一个完整的测试用例大概是这样的:

describe('Window blur dialog test', () => {
  it('should display Angular Material dialog when window loses focus', () => {
    cy.visit('/your-target-page');

    // 模拟窗口失焦行为
    cy.window().then(win => {
      Object.defineProperty(win.document, 'hidden', { value: true });
      win.dispatchEvent(new Event('visibilitychange'));
    });

    // 验证对话框已渲染并可见
    cy.get('mat-dialog-container')
      .should('be.visible')
      .contains('你的对话框标题或内容');
  });
});

额外注意事项

  • 如果你在headless模式下测试失败,但交互式模式正常,可以尝试检查是否有其他拦截焦点事件的逻辑,或者调整Cypress的浏览器启动参数。
  • 可以查看Angular Material对话框的相关源码,确认它具体监听的是哪个焦点相关事件,这样能更精准地模拟触发。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:27:57