You can interact with localStorage and sessionStorage directly within your Cypress tests, which is super handy for managing authentication tokens, user preferences, or any other client-side state your application relies on.
Let’s see it in action. Imagine you have a simple app that stores a user’s name in localStorage.
// In your application code (e.g., app.js)
document.getElementById('saveButton').addEventListener('click', () => {
const name = document.getElementById('nameInput').value;
localStorage.setItem('userName', name);
});
Here’s how you’d test that in Cypress:
// cypress/e2e/localStorage.cy.js
describe('localStorage Interaction', () => {
beforeEach(() => {
// Visit your app's page
cy.visit('/your-app-page');
});
it('should set and get localStorage items', () => {
const userName = 'CypressUser';
// Set an item in localStorage
cy.window().then((win) => {
win.localStorage.setItem('userName', userName);
});
// Verify it was set by reading it back
cy.window().then((win) => {
const storedName = win.localStorage.getItem('userName');
expect(storedName).to.equal(userName);
});
// You can also use Cypress commands to interact with the UI that uses localStorage
cy.get('#nameInput').type(userName);
cy.get('#saveButton').click();
// Now, check if the UI reflects the stored value or if the item persists
cy.get('#displayArea').should('contain', userName); // Assuming your app displays the name
});
it('should clear localStorage', () => {
// Set an item first
cy.window().then((win) => {
win.localStorage.setItem('testItem', 'someValue');
});
// Clear all localStorage items
cy.window().then((win) => {
win.localStorage.clear();
});
// Verify it's gone
cy.window().then((win) => {
expect(win.localStorage.getItem('testItem')).to.be.null;
});
});
it('should work with sessionStorage', () => {
const sessionData = 'sessionToken123';
// Set an item in sessionStorage
cy.window().then((win) => {
win.sessionStorage.setItem('authToken', sessionData);
});
// Verify it was set
cy.window().then((win) => {
const storedData = win.sessionStorage.getItem('authToken');
expect(storedData).to.equal(sessionData);
});
// Note: sessionStorage is cleared when the browser tab/window is closed.
// Cypress runs in a single browser instance for a test run, but if you were to
// manually close and reopen the browser, sessionStorage would be empty.
});
});
The core mechanism here is cy.window(). This command yields the window object of your application, which is exactly where localStorage and sessionStorage reside. Once you have the window object, you can call all the standard browser Web Storage API methods: setItem(key, value), getItem(key), removeItem(key), and clear().
localStorage is persistent across browser sessions. If you set an item in localStorage in one test, it will still be there when you run your next test, or even if you close and reopen your browser. This is why you often see localStorage.clear() in beforeEach or afterEach blocks in Cypress tests – it’s a good practice to ensure a clean slate for each test to prevent state leakage. sessionStorage, on the other hand, is cleared when the page session ends, which typically means when the browser tab or window is closed.
The most surprising thing about interacting with localStorage and sessionStorage in Cypress is that you’re not really interacting with them through the DOM or network requests; you’re directly manipulating the browser’s internal storage mechanisms. This allows for very fast and direct control over state that would otherwise require complex user interactions or API calls to set up. It’s like having a direct channel to the browser’s memory for that specific origin.
When managing authentication, you’ll often find yourself setting localStorage.setItem('authToken', 'your_token_here') in a before or beforeEach hook after a successful login API call or by directly injecting the token. Then, subsequent tests can read this token to make authenticated requests or verify UI elements that only appear for logged-in users.
A common pitfall is forgetting that localStorage and sessionStorage are scoped to the origin (protocol, domain, and port). If your application runs on http://localhost:3000 and then redirects to https://my-app.com, localStorage on the first origin won’t be accessible from the second. Cypress handles this by keeping tests within a single origin context unless explicitly told otherwise.
You’ll next encounter managing cookies, which, like localStorage and sessionStorage, are also part of browser storage but operate under different rules and are sent with HTTP requests.