Cypress Data Session

3.0.0 · active · verified Tue Apr 21

cypress-data-session is a Cypress plugin designed to streamline test data setup and reuse by implementing a powerful caching mechanism. It provides the `cy.dataSession` command, allowing developers to define how test data (like user objects, authentication tokens, or complex API responses) is created, validated, cached, and recreated if necessary. This plugin significantly speeds up test execution by avoiding repetitive, expensive data creation operations across multiple tests or even different spec files. Currently at v3.0.0, the package sees consistent maintenance and bug fixes, with major versions introducing breaking changes tied to Cypress core updates. Its key differentiator from Cypress's native `cy.session` command is its flexibility: `cy.dataSession` can cache *anything* (not just browser session state), provides direct access to cached data, supports custom validation logic, dependent caching, time limits, use count limits, and offers static utility methods, making it highly adaptable for complex test scenarios.

Common errors

Warnings

Install

Imports

Quickstart

This quickstart demonstrates how to configure `cypress-data-session` in `cypress.config.ts`, register the command in the support file, and then use `cy.dataSession` within a test spec to create, validate, and reuse a 'user' data object across tests, including backend cleanup.

import { defineConfig } from 'cypress';
import { setupNodeEvents } from 'cypress-data-session/plugin';

// cypress.config.ts
export default defineConfig({
  e2e: {
    setupNodeEvents(on, config) {
      setupNodeEvents(on, config); // Register plugin tasks
      // IMPORTANT: return the config object
      return config;
    },
    baseUrl: 'http://localhost:3000', // Example base URL
    specPattern: 'cypress/e2e/**/*.cy.{js,jsx,ts,tsx}',
  },
});

// cypress/support/e2e.ts
import 'cypress-data-session'; // Registers cy.dataSession command

// cypress/e2e/user.cy.ts
describe('User Management with Data Session', () => {
  const userSessionName = 'testUser';
  let createdUserId: string; // Store ID for cleanup

  beforeEach(() => {
    cy.dataSession({
      name: userSessionName,
      setup: () => {
        cy.log('Creating new user via API...');
        // In a real app, this would be an API call to create a user
        return cy.request('POST', '/api/users', {
          username: 'testuser_' + Date.now(), // Unique username
          password: 'password123',
        }).then((response) => {
          expect(response.status).to.eq(201);
          createdUserId = response.body.id;
          return { id: createdUserId, token: response.body.token }; // Data to cache
        });
      },
      validate: (cachedData: { id: string, token: string }) => {
        cy.log(`Validating user: ${cachedData.id}`);
        // Check if the user still exists and the token is valid
        return cy.request({
          method: 'GET',
          url: `/api/users/${cachedData.id}`, 
          headers: { Authorization: `Bearer ${cachedData.token}` },
          failOnStatusCode: false,
        }).then(response => response.status === 200);
      },
      recreate: (cachedData: { id: string, token: string }) => {
        cy.log(`Recreating session for user: ${cachedData.id}`);
        // Use the cached token to log in or set session state
        cy.setCookie('authToken', cachedData.token);
        cy.visit('/'); // Navigate to the app after setting session
      },
      onInvalidated: () => {
        cy.log(`Data session '${userSessionName}' was invalidated. Performing cleanup if needed.`);
        // Optional: specific cleanup actions if validation fails
      },
      shareAcrossSpecs: true, // Allow sharing this session across multiple spec files
      // expire: 3600000, // Optional: expire session after 1 hour
      recomputeOnRetry: true, // Optional: recompute session if a test retries
    }).then((user) => {
      cy.log(`Using cached/created user: ${JSON.stringify(user)}`);
      cy.wrap(user).as('currentUser'); // Alias the user data for the test
      createdUserId = user.id; // Ensure ID is updated for current test run
    });
  });

  it('should display the dashboard for the logged-in user', () => {
    cy.get('.welcome-message').should('be.visible').and('contain', 'Welcome, testuser');
    cy.get('@currentUser').its('id').should('eq', createdUserId);
  });

  it('should allow the user to access their profile page', () => {
    cy.visit('/profile');
    cy.get('.profile-details').should('contain', `User ID: ${createdUserId}`);
  });

  after(() => {
    // Cleanup the created user from the backend after all tests complete
    // This ensures a clean state for subsequent test runs
    if (createdUserId) {
      cy.request('DELETE', `/api/users/${createdUserId}`, { failOnStatusCode: false });
    }
  });
});

view raw JSON →