最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How can I call fetch from within a cypress test? - Stack Overflow

programmeradmin3浏览0评论

I'm using Cypress. I have a little React app and a little Flask backend. I want my test to make a call to the backend to set up the state it's going to operate on. I used fetch. This works fine. Except Cypress is mad and doesn't consider the test a success. I am not a javascript developer really so this might be obvious, but I can't figure out how to make it happy.

This is my test code:

    it.only("edits a job", async () => {
        const now = new Date().getTime()
        const title = `Edit-This-${now}`
        const newTitle = `SUCCESS-EDIT-${now}`
        const pany = `Edit Company-${now}`
        const link = `${now}`
        const status = "Edit Test"
        const body = JSON.stringify({pany, title, link, status})
        await fetch('/add_job', {method: 'post', headers: {'Content-Type': 'application/json'}, body: body})
        cy.visit("http://localhost:3000/jobs_list")
        cy.contains(title)
        cy.contains(pany)
        cy.contains(link)
        cy.contains(status)

        cy.get(`[name=edit-${title}`).click()
        cy.get(`[value=${title}`).clear().type(newTitle)
        cy.get(`[name=save-${newTitle}`).click()

        cy.contains(newTitle)
        console.log("what the heck")
        })

This seems to work just fine. But at the end, there's a CypressError:

Cypress mand timeout of 4530ms exceeded. (and Mocha's done() called multiple times)

I also tried not using async/await and putting the steps inside a then after fetch, but that didn't help. Passing done to the it block and calling done() at the end of that made it not run anything. That makes sense because cypress steps look synchronous but are in fact not, so it would have hit done() before executing any of them.

Making the function passed to it not async and changing fetch to

cy.request('POST', 'http://localhost:3000/add_job', {'Content-Type': 'application/json', pany, title, link, status})

instead of fetch seems to have worked, but I'd like to understand why.

I'm using Cypress. I have a little React app and a little Flask backend. I want my test to make a call to the backend to set up the state it's going to operate on. I used fetch. This works fine. Except Cypress is mad and doesn't consider the test a success. I am not a javascript developer really so this might be obvious, but I can't figure out how to make it happy.

This is my test code:

    it.only("edits a job", async () => {
        const now = new Date().getTime()
        const title = `Edit-This-${now}`
        const newTitle = `SUCCESS-EDIT-${now}`
        const pany = `Edit Company-${now}`
        const link = `https://example./edit-me-${now}`
        const status = "Edit Test"
        const body = JSON.stringify({pany, title, link, status})
        await fetch('/add_job', {method: 'post', headers: {'Content-Type': 'application/json'}, body: body})
        cy.visit("http://localhost:3000/jobs_list")
        cy.contains(title)
        cy.contains(pany)
        cy.contains(link)
        cy.contains(status)

        cy.get(`[name=edit-${title}`).click()
        cy.get(`[value=${title}`).clear().type(newTitle)
        cy.get(`[name=save-${newTitle}`).click()

        cy.contains(newTitle)
        console.log("what the heck")
        })

This seems to work just fine. But at the end, there's a CypressError:

Cypress mand timeout of 4530ms exceeded. (and Mocha's done() called multiple times)

I also tried not using async/await and putting the steps inside a then after fetch, but that didn't help. Passing done to the it block and calling done() at the end of that made it not run anything. That makes sense because cypress steps look synchronous but are in fact not, so it would have hit done() before executing any of them.

Making the function passed to it not async and changing fetch to

cy.request('POST', 'http://localhost:3000/add_job', {'Content-Type': 'application/json', pany, title, link, status})

instead of fetch seems to have worked, but I'd like to understand why.

Share Improve this question asked Aug 17, 2020 at 19:53 ohnonotagainohnonotagain 411 gold badge1 silver badge2 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 8

Use cy.request rather than fetch.

https://docs.cypress.io/api/mands/request

cy.request({yourUri}).as("response"); // This takes care of the async task. 
 
cy.get("@response").should((response) => { 
   // Carry on with the rest of your test
   cy.get("some selector");

});

https://docs.cypress.io/guides/core-concepts/introduction-to-cypress.html#Chains-of-Commands

It’s very important to understand the mechanism Cypress uses to chain mands together. It manages a Promise chain on your behalf, with each mand yielding a ‘subject’ to the next mand, until the chain ends or an error is encountered. The developer should not need to use Promises directly, but understanding how they work is helpful!

You can add items to the Cypress promise chain/queue via Cypress.Promise

You could likely wrap your fetch call use Cypress.Promise, but cy.request is remended for this unless you have some specific reason not to use it.

// wrap null, so that you can use `then` to invoke a callback as an arbitrary mand
// and return a Cypress.Promise - so that cypress will wait on it's result
// (or just use cy.request :))
cy.wrap(null).then(() => {
  return new Cypress.Promise((resolve, reject) => {
    try {
      fetch(/*...*/).then(resolve);
    } catch (e) {
      reject(e);
    }
  })
})

You can use fetch with async/await in cypress tests like this:

it('should do something', () => {
  const originalObject = { a: 1 }
  const options = {
    method: 'PUT',
    body: JSON.stringify(originalObject),
    headers: {
      'Content-Type': 'application/json',
      'Accept': 'application/json',
    },
  }

  cy.wrap(null).then(async () => {
    const response = await fetch('/echo', options)
    const echoedObject = await response.json()
    expect(echoedObject).to.deep.eq(originalObject)
  })
})
发布评论

评论列表(0)

  1. 暂无评论