如果元素存在,等待它消失

If element exists wait for it to disappear

所以我正在尝试编写一些柏树代码,但 imo 文档并不是很清楚。

我有两种情况。

  1. 加载页面时没有加载微调器。
  2. 页面加载了加载微调器。

我想编写满足这两种情况的代码,让测试继续进行。

  1. 如果页面没有加载微调器元素:照常继续测试。
  2. 如果页面确实有加载微调器元素:等到该元素消失,然后继续

Cypress 有很多花哨的功能,但关于如何使用它们的文档还不够清楚。

我尝试了以下代码:

  try {
    cy.getByTestId('loader-spinner')
      .should('exist')
      .then(el => {
        el.should('not.exist');
      });
  } catch (error) {
    cy.getByTestId('loader-spinner').should('not.exist');
  }

您应该可以只使用 should('not.exist') 断言,使 Cypress 等待元素不存在。请记住,赛普拉斯会自动重试直到超时,所以如果您没有更改全局超时,那么以下将最多尝试 4 秒。

cy.getByTestId('loader-spinner')
  .should('not.exist');

如果您发现测试失败是因为该元素仍然存在,您可以增加超时时间。下面,我为 should() 命令定义了 10 秒(10000 毫秒)超时。

cy.getByTestId('loader-spinner')
  .should('not.exist', { timeout: 10000 });

此外,您可能会发现该元素仍然存在,但不可见。在这种情况下,将 not.exist 更改为 not.be.visible

由于时间方面的原因,要正确完成此测试可能很棘手。

控制触发器

您真的需要知道控制微调器的是什么 - 通常是对 API 的调用。然后您可以延迟该调用(或者更确切地说是响应)以“强制”微调器出现。

为此,请使用 intercept

cy.intercept(url-for-api-call, 
  (req) => {
    req.on('response', (res) => res.delay(100))  // enough delay so that spinner appears
  }
)

// whatever action triggers the spinner, e.g click a button

cy.getByTestId('loader-spinner')  // existence is implied in this command
                                  // if the spinner does not appear 
                                  // the test will fail here

cy.getByTestId('loader-spinner').should('not.exist')  // gone after delay finishes

两种情况

首先,我认为您的两种场景想法不会帮助您正确编写测试。

您正在尝试使用 try..catch 进行条件测试(想法不错,但行不通)。问题是由于时间方面的原因,条件测试是不稳定的,你让测试在一个快速的环境中工作然后它开始在一个较慢的环境中中断(例如 CI)。

最好控制条件(如上面的延迟),然后在该条件下测试页面行为。

为了测试微调器没有出现,return拦截中的存根它应该足够快以防止微调器显示。

cy.intercept(url-for-api-call, {stubbed-response-object})

// whatever action triggers the spinner, e.g click a button

cy.getByTestId('loader-spinner').should('not.exist')  // never appears

看看When Can The Test Blink?