【问题标题】:How can I use cookies across multiple Cypress tests?如何在多个赛普拉斯测试中使用 cookie?
【发布时间】:2021-08-12 03:11:00
【问题描述】:

我正在使用cypress 来测试我的注册和登录表单。我想在我的register.js 测试中设置cookie,然后在我的login.js 测试中使用它们。

我将 cookie 保存在 cypress/support/index.js 中:

Cypress.Cookies.defaults({
  preserve: ['test_email', 'test_password'],
});

我的 register.js 测试如下所示:

describe('Create new account', () => {
  it('Visit Register', () => {
    cy.visit(Cypress.env('URL_REGISTER'));

    cy.setCookie('test_email', 'fake@email.com');
    cy.setCookie('test_password', 'abc123');
  });

  it('Fill out register form', async () => {
    const email = await cy.getCookie('test_email');
    const password = await cy.getCookie('test_password');

    cy.get('[data-cy="register-email"]').type(email.value);
    cy.get('[data-cy="register-password"]').type(password.value);
  });
});

当我运行这个测试时,我得到这个错误:

无法读取未定义的属性“值”

我知道cy.getCookie() 返回一个对象并且是异步的,这就是我尝试使用await 的原因,但由于某种原因,这似乎不起作用。如何在多个 cypress 测试中设置获取 cookie?

【问题讨论】:

    标签: javascript cookies cypress


    【解决方案1】:

    使用Cypress.preserveOnce()beforeEach() 为所有测试保留测试之间的cookie。

    beforeEach(() => {
      Cypress.Cookies.preserveOnce('test_email')
    })
    
    it('set cookie', async () => {
      cy.setCookie('test_email', 'fake@email.com')
    })
    
    it('once', async () => {
      const email = await cy.getCookie('test_email')
      expect(email).to.have.property('value', 'fake@email.com')  // passes
    })
    
    it('twice', async () => {
      const email = await cy.getCookie('test_email')
      expect(email).to.have.property('value', 'fake@email.com')  // passes
    })
    
    it('thrice', async () => {
      const email = await cy.getCookie('test_email')
      expect(email).to.have.property('value', 'fake@email.com')  // passes
    })
    

    您应该坚持使用 getCookie 的文档化方式。

    如果我跑步

    const email = await cy.getCookie(...)
    

    cy.visit() 之后,我得到未定义。

    如果我使用

    cy.getCookie(...).then(...) 
    

    在下一行获取值。

    由于赛普拉斯没有在任何地方记录 await 语法,您可能会得到一些不稳定的结果。

    标准模式是:

    it('once', () => {
      cy.getCookie('test_email').then(email => {
        expect(email).to.have.property('value', 'fake@email.com')  // passes
      })
    })
    

    如果您在 CI 中运行测试,它们可能会并行运行,因此最好在 before()beforeEach() 中设置Cookie。

    before(() => {
      cy.setCookie('test_email', 'fake@email.com')
    })
    
    beforeEach(() => {
      Cypress.Cookies.preserveOnce('test_email')
    })
    
    it('uses cookie once', () => {
      ...
    })
    
    it('uses cookie twice', () => {
      ...
    })
    
    it('uses cookie thrice', () => {
      ...
    })
    

    【讨论】:

    • 我在我的cypress/support/index.js 中使用全局Cypress.Cookies.defaults({preserve: ['test_email', 'test_password']});。我喜欢将setCookie 语句移动到before() 的想法。我尝试使用传统的异步方法,当我自己运行测试时它可以工作,但是当我同时运行两个测试时,我的下一个 login.js 测试失败。当两个测试一起运行时,就好像 register.js 测试的运行方式不同。在使用 login.js 测试运行时,它不会记录 type 事件,但它本身会记录。
    • 所以,您已经知道如何在多个赛普拉斯测试中使用 cookie。
    • 你绝对应该放弃const email = await cy.getCookie(...)。如果我在cy.visit() 之后运行它,我会得到未定义,但如果我在下一行使用cy.getCookie(...).then(...),它会得到值。由于 Cypress 没有在任何地方记录 await 语法,因此您是在掷骰子。
    猜你喜欢
    • 1970-01-01
    • 2023-02-14
    • 1970-01-01
    • 1970-01-01
    • 2023-02-18
    • 1970-01-01
    • 1970-01-01
    • 2021-10-29
    • 1970-01-01
    相关资源
    最近更新 更多