赛普拉斯在单独的测试中两次触发cy.wait(1000)

时间:2020-01-13 16:07:22

标签: angular e2e-testing cypress

在Angular Cypress E2E测试中,我要测试一个凌乱的szenario:填写注册表(localhost)并发送,然后转到(Fake-)Mailbox并收集验证电子邮件。由于FakeSMTP需要一些时间,因此我想等一下再访问它

it('should submit the registration', () => {
  cy.visit('https://localhost/register);
  ...
  cy.get('button[type=submit]').should('not.be.disabled').click();
});

// Collect the Mail
it('should collect the registration activation email', () => {

  /**
   * Wait 10 Seconds for E-Mail to arrive
   */
  cy.wait(10000); // --> this fires twice

  cy.visit('https://localhost:5080');
  ...
});

为什么cy.wait(10000)会触发两次?第一次(最后一件事),第二次实际在电子邮件集合中提交。

2 个答案:

答案 0 :(得分:2)

我认为赛普拉斯遇到新域时会重置第二项测试,请参见此评论Change baseUrl during test

Cypress更改父域以匹配baseUrl,以避免在与父域不匹配的网站上导航时出现问题。赛普拉斯产品只是未编码为可处理更改baseUrl中间测试的情况。

要检查出来,这个简单的测试反映了发生的情况

describe('changing domains', () => {

  it('goes to example.com', () => {
    cy.visit('http://example.com')
  })

  it('changes to example.net', () => {
    cy.wait(10000)
    cy.visit('http://example.net')
  })
})

有两种方法可以(潜在地)避免该问题,不确定哪种方法对您有用。

  1. 在第二次测试中,先通过虚拟呼叫进入新域,
describe('changing domains', () => {

  it('goes to example.com', () => {
    cy.visit('http://example.com')
  })

  it('changes to example.net', () => {
    cy.visit('http://example.net')
    cy.wait(10000)
    cy.visit('http://example.net')
  })
})
  1. 在第一个测试中等待,
describe('changing domains', () => {

  it('goes to example.com', () => {
    cy.visit('http://example.com')
    cy.wait(10000)
  })

  it('changes to example.net', () => {
    cy.visit('http://example.net')
  })
})

理想的解决方案是将FakeSMTP服务器从测试中删除,并以与cy.route()捕获和存根XHR帖子相同的方式来捕获发送的邮件,那么您不必等待10s,但是我看不到任何示例,因此假定尚不可能。也许是本地事件到来的时候。


我看过这篇文章Testing an email workflow from end to end with Cypress,该文章使用递归创建了一个自定义命令来轮询服务器,直到电子邮件出现为止。从本质上讲,它就像一个cypress命令重试,因此您不必等待任何时间(如@Jboucly应当避免),而是以300ms的增量等待直到电子邮件到达。

Cypress.Commands.add('getLastEmail', email => {
  function requestEmail() {
    return cy
      .request({
        method: 'GET',
        url: 'http://localhost:4003/last-email',
        headers: {
          'content-type': 'application/json',
        },
        qs: {
          email,
        },
        json: true,
      })
      .then(({ body }) => {
        if (body) {
          return body;
        }

        // If body is null, it means that no email was fetched for this address.
        // We call requestEmail recursively until an email is fetched.
        // We also wait for 300ms between each call to avoid spamming our server with requests
        cy.wait(300);

        return requestEmail();
      });
  }

  return requestEmail();
});

它确实应该有一个递归深度限制,以防万一事情没有按预期进行并且电子邮件永远不会到达。

答案 1 :(得分:0)

尝试一下:)

cy.visit('http=//localhost:5080').wait(10000);

赛普拉斯强烈建议不要单独使用cy.wait (),请参见here

doc中,要尊重良好的操作习惯(如果可能,请使用您的邮件实用程序)是使用其API来检索邮件,而不是通过界面进行操作