Skip to main content

Command Palette

Search for a command to run...

đź”’ Securing Your E2E Tests: How to Handle Cypress Secrets in GitLab CI/CD

Published
•4 min read

One of the first security hurdles in setting up a robust CI/CD pipeline for end-to-end (E2E) testing is figuring out where to put sensitive data like user credentials, API keys, and environment-specific configurations.

If you’ve been running Cypress tests locally, chances are you’ve used a .env file or hardcoded values. But when it’s time to push your automated tests to a GitLab CI/CD pipeline, how do you safely give your jobs access to that sensitive password without exposing it in your repository or build logs?

The answer lies in GitLab’s built-in, secure secret management tool: CI/CD Variables.

The Problem: Local Secrets vs. CI/CD Security

❌ What NOT to Do

  1. Do not commit .env files: Never push files containing secrets (like .env or cypress.env.json with real credentials) to your Git repository. Always ensure these files are listed in your .gitignore.

  2. Do not hardcode secrets: Embedding passwords directly into your Cypress test files or configuration files is a major security risk.

When your automated tests run in the cloud, they need the secrets to function, but they must retrieve them from a location that is secure and independent of the source code.

The Solution: GitLab CI/CD Variables

GitLab CI/CD Variables provide a mechanism to define environment variables that are injected only when a job executes. They offer crucial security features that make them ideal for handling Cypress secrets.

Step 1: Securely Define the Variable in GitLab

This step moves the password out of your codebase and into a protected environment.

  1. Navigate to your GitLab project.

  2. Go to Settings > CI/CD.

  3. Expand the Variables section.

  4. Click Add variable and fill in the fields:

    • Key: Use a descriptive name, often prefixed with CYPRESS_ for auto-detection (e.g., CYPRESS_TEST_USER_PASSWORD).

    • Value: Enter the actual secret value (e.g., MyS3cur3P@ssw0rd).

    • Type: Keep it as Variable.

    • Protect variable (Crucial): Check this box. This ensures the variable is only available to jobs running on protected branches (like main or master).

    • Mask variable (Critical): Check this box. This is the most important step for security. GitLab will automatically replace the variable's value with [MASKED] in all job logs, screenshots, and videos, preventing accidental exposure.

Step 2: Access the Secret in Your Cypress Tests

Cypress is designed to easily consume environment variables. By following the naming convention CYPRESS_<YOUR_KEY>, Cypress automatically loads the variable into its Cypress.env() object.

In your JavaScript test file, you can access the secret like this:

JavaScript

// cypress/e2e/login.cy.js

describe('Secure Login Test', () => {
  it('should log in using credentials from CI/CD variables', () => {
    // 1. Access the variable using Cypress.env()
    // Note: The 'CYPRESS_' prefix is dropped when accessing it inside the test.
    const username = Cypress.env('TEST_USER_USERNAME'); // Assuming another variable is set
    const password = Cypress.env('TEST_USER_PASSWORD');

    cy.visit('/login');

    // 2. IMPORTANT: Hide the input value from the Cypress Command Log
    // Use the { log: false } option in the .type() command.
    cy.get('#username').type(username, { log: false });
    cy.get('#password').type(password, { log: false }); // The secret is now hidden!

    cy.get('button[type="submit"]').click();
    cy.url().should('include', '/dashboard');
  });
});

Step 3: Run the Pipeline (.gitlab-ci.yml)

Your CI configuration file remains clean and simple because GitLab handles the environment variable injection automatically before the script stage runs.

YAML

stages:
  - e2e_test

e2e_testing:
  stage: e2e_test
  image: cypress/included:latest # Using a convenient Cypress Docker image
  script:
    # GitLab automatically injects CYPRESS_TEST_USER_PASSWORD here
    - npx ci
    - npx cypress run --browser chrome

  # Ensure this job only runs on a protected branch that has access to the variable
  only:
    - main

Summary of Best Practices

Security Measure

Purpose

GitLab Variable Protection

Restricts secret access only to protected branches (main).

GitLab Variable Masking

Prevents the secret from being visible in job logs, screenshots, and videos.

CYPRESS_ Prefixing

Allows Cypress to automatically load the CI variable into Cypress.env().

{ log: false } in .type()

Prevents the password from being written to the Cypress Command Log during test execution.

By leveraging GitLab CI/CD Variables and Cypress's native environment handling, you can maintain a high security standard while ensuring your automated E2E tests have all the necessary information to run successfully.

More from this blog

C

Code & Quality | Test Automation Insights

9 posts