Tìm kiếm trang web

typescript - Chờ một yêu cầu bị chặn không hoạt động như mong đợi


Tôi cần kiểm tra trạng thái của mã xác minh email đã thay đổi sau khi xác minh email.

Đầu tiên tôi tạo một người dùng, sau đó tôi nhận URL xác minh email được gửi đến người dùng và cuối cùng truy cập liên kết này.

Khi truy cập liên kết ứng dụng, nó gửi token xác thực đến API để đánh dấu email đã được xác minh. Tôi cần cypress chờ phản hồi từ API, để tôi có thể tiếp tục kiểm tra...

it('ensure create a user and verify the email address', () => {
  // Create the user
  cy.request('POST', 'app/sign-up.json', {
    user: {
      userName: 'new_user',
      email: '[email ',
      password: 'password',
      fullName: 'new user full name'
    }
  }).should((response) => {
    expect(response.status).to.eq(201)
    // Check if user has been created in database
    cy.task('prisma:user:findMany', {}).then(async (result: any) => {
      expect(result.length).to.eq(1)
      // Get email verification link
      cy.task<Array<BeeQueue.Job<IEmail>>>('beeQueue:emailService:getJobs', 'waiting')
        .should('exist')
        .should('have.length', 1)
        .then((result) => {
          if (result[0].data.text !== null && result[0].data.text !== undefined) {
            const tokenUrl = result[0].data.text.substring(result[0].data.text.lastIndexOf('http://'))
            // Intercept API request
            cy.intercept('GET', '/app/verify_email.json?*').as('verifyEmail')
            cy.visit(tokenUrl.substring(tokenUrl.indexOf('/app')))
            //
            // Here the logic doesn't work, cypress doesn't wait for the request response
            //
            cy.wait('@verifyEmail').its('response.statusCode').should('equal', 200)
          }
        })
    })
  })
})

Trong hình ảnh, chúng ta có thể thấy rằng yêu cầu xảy ra sau .wait()

Trong hình tiếp theo, tôi đã sử dụng wait trước khi chờ để chặn .wait(2000)

cy.wait(2000)
cy.wait('@verifyEmail').its('response.statusCode').should('equal', 200)

Tôi không nghĩ cách này (sử dụng chờ cố định) là cách thông minh để làm. Nhưng nếu chỉ có cách này, thì tại sao lại dùng chờ với chặn?

Câu trả lời #1

Tôi nghi ngờ nó liên quan đến việc sử dụng cy.visit(). Đôi khi Cypress sẽ đặt lại trình chạy khi có một cuộc gọi được thực hiện với visit().

Lý do tôi nghi ngờ điều đó là, trong nhật ký đầu tiên cy.wait('@verifyEmail') đã tìm thấy một yêu cầu, nhưng phản hồi là undefined như thể yêu cầu đã bị hủy.

Bạn có thể nhận được kết quả tốt hơn bằng cách sử dụng cy.request() thay vào đó.

it('ensure create a user and verify the email address', () => {
  // Create the user
  cy.request('POST', 'app/sign-up.json', {
    user: {
      userName: 'new_user',
      email: '[email ',
      password: 'password',
      fullName: 'new user full name'
    }
  }).should((response) => {
    expect(response.status).to.eq(201)
    // Check if user has been created in database
    cy.task('prisma:user:findMany', {}).then(async (result: any) => {
      expect(result.length).to.eq(1)
      // Get email verification link
      cy.task<Array<BeeQueue.Job<IEmail>>>('beeQueue:emailService:getJobs', 'waiting')
        .should('exist')
        .should('have.length', 1)
        .then((result) => {
          if (result[0].data.text !== null && result[0].data.text !== undefined) {
            const tokenUrl = result[0].data.text.substring(result[0].data.text.lastIndexOf('http://'))

            cy.request(tokenUrl.substring(tokenUrl.indexOf('/app')))
              .then((response) => {
                expect(response.status).to.equal(200)
              })
          }
        })
    })
  })
})

Câu trả lời #2

(Vậy là bạn đang cư xử một cách bất ngờ trong Cypress)

Trước mỗi bài kiểm tra, hai nhiệm vụ được thực hiện để làm sạch hàng đợi redis và xóa dữ liệu từ cơ sở dữ liệu. Tôi đã truyền một callback vào hàm beforeEach với đối số done.

beforeEach((done) => {
   cy.clearDb().then(() => {
     cy.clearEmailQueueJobs()
     done()
   })
})

Vào một thời điểm nào đó, một trong những nhiệm vụ này đã thất bại và tôi không phát hiện ra lỗi.

Như Fody đã nói, Cypress đang đặt lại runner và trả về undefined, và bây giờ chúng ta biết lý do tại sao.

Nhìn vào hình dưới đây, bạn có thể thấy một lỗi trong Cypress.

Giải pháp là truyền một callback mà không có đối số done và để Cypress xử lý lỗi tác vụ

beforeEach(() => {
  cy.clearDb()
  cy.clearEmailQueueJobs()
})

Bây giờ mọi thứ hoạt động như mong đợi.

Bài viết liên quan