【问题标题】:How can I call fetch from within a cypress test?如何从柏树测试中调用 fetch?
【发布时间】:2020-08-17 19:53:34
【问题描述】:

我正在使用Cypress。我有一个小的 React 应用程序和一个小的 Flask 后端。我希望我的测试调用后端来设置它将运行的状态。我用取。这工作正常。除了赛普拉斯疯了,不认为测试成功。我真的不是 javascript 开发人员,所以这可能很明显,但我不知道如何让它快乐。

这是我的测试代码:

    it.only("edits a job", async () => {
        const now = new Date().getTime()
        const title = `Edit-This-${now}`
        const newTitle = `SUCCESS-EDIT-${now}`
        const company = `Edit Company-${now}`
        const link = `https://example.com/edit-me-${now}`
        const status = "Edit Test"
        const body = JSON.stringify({company, 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(company)
        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")
        })

这似乎工作得很好。但最后,有一个 CypressError:

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

我也尝试过不使用 async/await 并在 fetch 之后将步骤放在 then 中,但这没有帮助。将done 传递给it 块并在最后调用done() 使其不运行任何东西。这是有道理的,因为 cypress 步骤看起来是同步的,但实际上并非如此,因此它会在执行任何步骤之前点击 done()

使传递给 it 的函数不是异步的,并将 fetch 更改为

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

而不是fetch 似乎有效,但我想了解原因。

【问题讨论】:

    标签: javascript cypress


    【解决方案1】:

    使用cy.request 而不是fetch

    https://docs.cypress.io/api/commands/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");
    
    });
    
    

    【讨论】:

      【解决方案2】:

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

      了解赛普拉斯用于将命令链接在一起的机制非常重要。 它代表你管理一个 Promise 链,每个命令都会为下一个命令产生一个“主题”,直到链结束或遇到错误。 开发人员不需要直接使用 Promises,但了解它们的工作原理会很有帮助!

      您可以通过Cypress.Promise将项目添加到赛普拉斯承诺链/队列

      您可能会使用 Cypress.Promise 封装您的 fetch 调用,但建议您为此使用 cy.request,除非您有特定的理由不使用它。

      // wrap null, so that you can use `then` to invoke a callback as an arbitrary command
      // 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);
          }
        })
      })
      

      【讨论】:

      • 我会在此处添加 ECMAScript async-await 和 Promise 规范参考的链接或指南。作者说他对JS不熟悉,所以对他有很大帮助。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多