anonymous coward
anonymous coward

Reputation: 12814

How to assert localStorage in Cypress

I worry that I'm doing this incorrectly, but the docs don't have an explicit example that I've found.

I have a test that walks thru the login flow. I also want to verify that certain values have been set inside localStorage once we're logged in.

When I do the following, I get an AssertionError, "expected null to exist":

describe("Trying to log in...", function() {
  it("Visits the Home Page", function() {
    cy.visit("/") // Uses baseUrl prefix from config

    // [ ... snip ... ]

    // Form should be visible and fillable now!
    cy.get("form")
      .should("be.visible")
      .within(() => {
        cy.findByLabelText(/email address/i)
          .should("exist")
          .should("be.visible")
          .click() // Clicking the label should focus the element:
          .type("[test username]")
        cy.findByLabelText(/password/i)
          .click()
          .type("[test password]")
        cy.findByText(/sign in/i).click()
      })

    // Now we're logged in... 

    cy.url().should("include", "home")

    // ========= THE FOLLOWING BREAKS: =======================
    // Check for our localStorage item:
    expect(localStorage.getItem("KeyToOurValue")).to.exist()
  })
})

However, if I put that expect in a callback to the last should, it seems to work?

describe("Trying to log in...", function() {
  it("Visits the Home Page", function() {
    cy.visit("/") // Uses baseUrl prefix from config

    // [ ... snip ... ]

    // Form should be visible and fillable now!
    cy.get("form")
      .should("be.visible")
      .within(() => {
        cy.findByLabelText(/email address/i)
          .should("exist")
          .should("be.visible")
          .click() // Clicking the label should focus the element:
          .type("[test username]")
        cy.findByLabelText(/password/i)
          .click()
          .type("[test password]")
        cy.findByText(/sign in/i).click()
      })

    // Now we're logged in... 

    cy.url().should("include", "home", ()=> {
        // ========= THE FOLLOWING WORKS! ========
        // Check for our localStorage item:
        expect(localStorage.getItem("KeyToOurValue")).to.exist()
    })
  })
})

Is that how I should do this?

It seems like I should be able to do it the first way?

What's the correct way to asset something about localStorage values after a certain cy line has run?

Upvotes: 16

Views: 14470

Answers (1)

Hung Tran
Hung Tran

Reputation: 1645

Should you assert localStorage inside the should block? Yes, you should. Check out the official example from Cypress


For cy-commands (cy.put, cy.get ...), they're enqueued and runs one after another later by Cypress. On the other hand, non cy-commands (expect) are executed right away. Hence, your localStorage is not available if you leave expect outside should() because sign-in is not finished yet.

By moving expect inside should, that means it's run after cy.url() is done. Since cy.url is the last item in Cypress' internal queue, the other cy commands (cy.visit, cy.get, cy.findBy...) have been completed by this point.

Upvotes: 19

Related Questions