Skip to content

Cypress - 隐藏元素

现代 Web 应用程序通常包含一些非立即可见的元素,例如悬停时出现的子菜单,或动态加载的内容。这些元素可能使用 CSS 属性(如 display: none; 或 visibility: hidden;)隐藏。Cypress 提供了强大的机制来与这些隐藏元素进行交互。

一个常见的场景是只有当你悬停在主菜单项上时才会出现的子菜单。我们来探讨 Cypress 处理这些情况的两种主要方法。

Cypress 可以利用 jQuery 方法来操作 DOM 元素。invoke('show') 命令在选中的元素上调用 jQuery 的 show() 方法。这个方法通常会改变元素的 CSS(例如,从 display: none 到 display: block),使其变为可见并因此可交互。

当你需要以编程方式确保元素可见后再与其交互时,这种方法很有用,它可以有效绕过通常会使其显示的某些用户交互(如悬停)。

考虑一个假设的电商网站场景,其中 ‘Sign In’ 链接位于一个最初隐藏的浮动菜单中:

describe('Hidden Elements Test - invoke(show)', () => {
it('Should interact with a hidden element after making it visible', () => {
// Example: Visit a page with a hidden flyout menu
cy.visit("https://www.example.com"); // Replace with your test page
// Assume '#accountMenuFlyout' is the hidden container
// and it becomes visible on hover of '#accountMenuTrigger'
// We directly make the flyout visible
cy.get('#accountMenuFlyout').invoke('show');
// Now that it's shown, we can click the 'Sign In' link within it
// Using a more specific selector for 'Sign In' is recommended
cy.get('#accountMenuFlyout').contains('Sign In').click();
// Add assertions for the expected outcome, e.g., navigation to sign-in page
cy.url().should('include', '/signin');
});
});

在 Cypress 命令日志中,你会看到 invoke 命令,紧接着是 click 命令。该元素虽然最初是隐藏的,但通过 invoke('show') 变得可见,然后成功被点击。

Cypress 有一个强大的特性,可以强制对元素执行动作,绕过其默认的可操作性检查。对于点击隐藏元素,你可以使用 cy.click({ force: true })。

这个选项告诉 Cypress 即使元素是隐藏的、被覆盖的或在正常情况下不被认为是“可点击”的,也要点击它。虽然方便,但应谨慎使用。

  • 绕过安全检查: force: true 会跳过可见性、元素是否禁用以及是否被覆盖等检查。这意味着即使真实用户无法与该元素交互,你的测试也可能通过。
  • 掩盖问题: 过度使用会掩盖应用程序中的真实 bug(例如,本应可见的元素却隐藏了)。
  • 何时使用: 它适用于那些通过编程方式隐藏但仍然是有效用户流程一部分的元素(例如,自定义样式的 radio button,其中实际的 <input type="radio"> 是隐藏的,而你与一个有样式的 <span> 交互),或者当模拟难以通过标准用户操作触发的事件时。

以下是使用 force: true 点击一个隐藏的 ‘Sign In’ 链接的示例:

describe('Hidden Elements Test - force:true', () => {
it('Should force click a hidden element', () => {
// Example: Visit a page with a hidden sign-in link
cy.visit("https://www.example.com"); // Replace with your test page
// Assume '.hidden-signin-link' is a selector for an element that is display:none
// A more robust selector like data-cy attribute is recommended in real projects.
cy.contains('Sign In') // Or a more specific selector for the hidden link
.click({ force: true });
// Add assertions for the expected outcome
cy.url().should('include', '/signin');
});
});

执行日志将显示执行了 click 命令,Cypress 将指示该动作是强制执行的。这种方法直接与元素交互,尽管它处于隐藏状态。

尽可能尝试像用户一样与你的应用程序交互。如果一个元素在悬停后变得可见,考虑使用 cy.get('.trigger-element').trigger('mouseover') 然后与现在可见的元素进行交互。如果一个元素在动画后出现,可以在交互前使用 Cypress 内置的重试能力和断言,如 .should('be.visible')。

有关可操作性和与元素交互的进一步阅读,请参阅 Cypress 官方文档关于“交互”和“可操作性”的部分。