为什么在beforeEach中设置的本地存储在实际的Cypress测试中不是持久性的?

huangapple go评论52阅读模式
英文:

Why is local storage set in beforeEach not persistent in actual cypress test?

问题

'Add Article'按钮仅在用户已登录时显示(我们在本地存储中有一个特定值的 'user' 键)

即使我在 beforeEach 方法中将 'user' 键设置为本地存储中,测试仍会失败,因为它无法找到 'New Article' 按钮,显然用户看起来不像已登录

beforeEach(() => {
    let res;
    cy.request({
        method: "POST",
        url: "http://localhost:3000/api/users/login",
        body: {
            "user": {
                "email": "test@test.com",
                "password": "test"
            }
        }
    }).then(response => {
        res = response
    })
    cy.visit("http://localhost:3000", {
        onBeforeLoad: function(win) {
            win.localStorage.setItem('user', JSON.stringify(res.body.user))
        }
    })
})

it("Add Article", () => {
    cy.contains("New Article").click()
    cy.get("input[placeholder='Article Title']").type("Article on cypress")
    cy.get("input[placeholder='What\\'s this article about?']").type("Topic is cypress")
    cy.get("[placeholder='Write your article (in markdown)']").type("Content of article")
    cy.get("input[placeholder='Enter tags']").type("Test Automation")
    cy.contains("button", "Publish Article").click()
    cy.contains("button", "Publish Article").click()
})
英文:

The 'Add Article' button is present only if the user is logged in (we have in local storage 'user' key with a specific value)
Even if I set the 'user' key to local storage in beforeEach method, the test fails because it can not find the 'New Article' button, because apparently the user does not appear as logged in

beforeEach(() => {


        let res;
        cy.request({
            method: "POST",
            url: "http://localhost:3000/api/users/login",
            body: {
                "user": {
                    "email":"test@test.com",
                    "password":"test"
                }
            }
        }).then(response => {
            res = response
        })
        cy.visit("http://localhost:3000", {
            onBeforeLoad: function(win) {
                win.localStorage.setItem('user', JSON.stringify(res.body.user))
            }
        })
    })

    it("Add Article", () => {
        cy.contains("New Article").click()
        cy.get("input[placeholder='Article Title']").type("Article on cypress")
        cy.get("input[placeholder='What\\'s this article about?']").type("Topic is cypress")
        cy.get("[placeholder='Write your article (in markdown)']").type("Content of article")
        cy.get("input[placeholder='Enter tags']").type("Test Automation")
        cy.contains("button", "Publish Article").click()
        cy.contains("button", "Publish Article").click()
    })

答案1

得分: 2

使用在命令之外定义的“闭包”变量通常会很棘手,因为像cy.request()这样的命令需要时间来解析。

您可以尝试将访问操作移到.then()回调内部,以确保该值来自响应,并且不要依赖于闭包变量。

beforeEach(() => {

  cy.request({
    ...
  }).then(response => {
    cy.visit("http://localhost:3000", {
      onBeforeLoad: function(win) {
        win.localStorage.setItem('user', JSON.stringify(response.body.user))
      }
    })
  })
英文:

Using "closure" variables that are defined outside of commands is often dicey, because the commands like cy.request() take time to resolve.

You can try moving the visit inside the .then() callback, which guarantees the value is coming from the response, and don't rely on the closure variable.

beforeEach(() => {

  cy.request({
    ...
  }).then(response => {
    cy.visit("http://localhost:3000", {
      onBeforeLoad: function(win) {
        win.localStorage.setItem('user', JSON.stringify(response.body.user))
      }
    })
  })

答案2

得分: 2

另一种方法是将响应保存到别名中。您可能会在cy.request()的回调函数内部调用cy.visit()时遇到问题。别名是在这种情况下效果很好的外部变量替代品。

let res
beforeEach(() => {

  cy.request({
    ...
  }).as('res')     // 在这里保存到别名

  cy.get('@res').then(response => {
    cy.visit("http://localhost:3000", {
      onBeforeLoad: function(win) {
        win.localStorage.setItem('user', JSON.stringify(response.body.user))
      }
    })
  })
})
英文:

Another way is to save the response to an alias. You may experience problems invoking cy.visit() inside the callback function of cy.request(). An alias is an alternative to external variables that works well in this situation.

let res
beforeEach(() => {

  cy.request({
    ...
  }).as('res')     // save to alias here

  cy.get('@res').then(response => {
    cy.visit("http://localhost:3000", {
      onBeforeLoad: function(win) {
        win.localStorage.setItem('user', JSON.stringify(response.body.user))
      }
    })
  })
})

huangapple
  • 本文由 发表于 2023年7月17日 18:16:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/76703465.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定