Verificando autenticación…

Skip to main content

Cypress E2E Tests Template

Purpose and Scope

This project provides a base template for creating End-to-End (E2E) tests using Cypress and Cucumber (Gherkin) for web applications. Its primary goal is to facilitate the initial setup of an automated testing environment, including integration with Azure Active Directory (AAD) for authentication, and the generation of detailed test reports.

Problem It Solves:

  • Standardizes the creation of E2E test projects with Cypress.
  • Provides a preconfigured solution for AAD authentication in Cypress tests.
  • Facilitates running tests in different environments (dev, intg, cert, prod).
  • Integrates report generation with Mochawesome.

Scope:

  • Configuration and execution of E2E tests for user interfaces (UI).
  • Configuration and execution of API tests.
  • Integration with Cucumber for Behavior-Driven Development (BDD).
  • Handling of environment-specific configurations.
  • Authentication with Azure AD.
  • Test report generation.
  • Integration with CI/CD pipeline (Jenkins).

Architecture

The project focuses on test automation with Cypress. The architecture is as follows:

  1. Cypress Test Runner: The main engine that runs test scripts.
  2. Application Under Test (AUT): The external web application or API being tested (e.g. strategic-planning.dev.appslatam.com).
  3. Cucumber (Gherkin): Allows writing test cases in natural language (.feature files) that map to JavaScript/TypeScript code (step definitions).
  4. Azure Active Directory (AAD): For tests requiring authentication, the project includes a custom flow to handle AAD login.
  5. Mochawesome: HTML report generator for visualizing test results.
  6. Node.js Environment: Cypress and its dependencies run on Node.js.
  7. Jenkins CI/CD: The Jenkinsfile defines the pipeline for automated test execution in continuous integration environments.

A complex architecture diagram is not required, as this is a testing project. The main interaction is Cypress communicating with the AUT over HTTP/HTTPS and manipulating the browser DOM.

Technologies and Dependencies

The main technologies and dependencies of the project are defined in the package.json file:

  • Testing Framework: Cypress (^13.14.1)
  • BDD (Behavior-Driven Development):
    • @badeball/cypress-cucumber-preprocessor: (^20.1.2) to integrate Cucumber with Cypress.
  • File Preprocessor:
    • @bahmutov/cypress-esbuild-preprocessor: (^2.2.2) to use ESBuild with Cypress.
    • esbuild: (^0.23.1) fast bundler for JavaScript/TypeScript.
  • Reporting:
    • mochawesome: (^7.1.3) to generate HTML reports.
    • mochawesome-merge: (^4.3.0) to merge multiple Mochawesome JSON reports.
    • mochawesome-report-generator: (^6.2.0) base report generator for Mochawesome.
  • Environment Variable Management:
    • dotenv: (^16.4.5) to load environment variables from a .env file.
  • Utilities:
    • fs-extra: (^11.2.0) for extended file system operations.
  • Runtime Environment: Node.js (recommended version >=16)

Local Setup

Prerequisites

  • Node.js (v16 or higher recommended)
  • npm (usually bundled with Node.js) or Yarn
  • A code editor (e.g. VSCode)
  • Git

Setup Steps

  1. Clone the repository: Follow these steps

  2. Install dependencies:

    npm install

    or if you use Yarn:

    yarn install
  3. Configure environment variables: Create a .env file at the project root. This file is ignored by Git (.gitignore). Based on cypress.config.js and cypress/support/e2e.js, the following variables are required for AAD authentication:

    # Credentials for the editor role user (example)
    AUTH0_USERNAME="tu_usuario_editor_aad@example.com"
    AUTH0_PASSWORD="tu_password_editor_aad"

    # Credentials for the reader role user (example)
    AUTH1_USERNAME="tu_usuario_lector_aad@example.com"
    AUTH1_PASSWORD="tu_password_lector_aad"

    Replace the values with the corresponding credentials for your test environments.

  4. Verify Cypress installation (optional):

    npm run cypress:verify
    # or
    npx cypress verify

Running Tests Locally

The package.json file contains several scripts to run tests:

  • Open Cypress Test Runner (UI):

    npm run cy:open

    This will open the Cypress interface where you can select and run tests individually.

  • Run all tests in the console (headless, Chrome by default):

    npm run cy:run
  • Run UI tests with Mochawesome report:

    npm run cy:ui
  • Run API tests with Mochawesome report:

    npm run cy:api
  • Run tests for a specific environment: The project is configured to load different baseUrl values depending on the environment.

    npm run cy:run:dev # For development environment
    npm run cy:run:intg # For integration environment
    npm run cy:run:cert # For certification environment
    npm run cy:run:prod # For production environment

    These scripts use configuration files in cypress/config/cypress.[entorno].config.json.

  • Generate Consolidated Report: After running tests with Mochawesome (e.g. npm run cy:run:dev), you can generate a consolidated HTML report:

    npm run cy:report

    This will create a merged-report.json file and open the HTML report at mochawesome-report/merged-report.html.

Deployment

Deployment of this testing project refers to its execution in a Continuous Integration (CI) environment, typically Jenkins.

Jenkins

The project includes a Jenkinsfile:

#!groovy
pipelineLatamEMX("cypress-e2e")

This indicates that it uses a shared pipeline called pipelineLatamEMX with the cypress-e2e profile. This pipeline will:

  1. Clone the repository.
  2. Install dependencies.
  3. Run Cypress tests (likely using one of the package.json scripts).
  4. Publish test artifacts (Mochawesome reports, videos, screenshots).

Environment Configuration in CI

Configuration for different environments (dev, intg, cert, prod) in CI is managed through YAML files in the deploy/env/ directory:

  • deploy/env/dev.yaml
  • deploy/env/cert.yaml
  • deploy/env/intg.yaml
  • deploy/env/feature.yaml

These files may contain environment-specific variables, such as AAD credentials:

# Example deploy/env/dev.yaml
### ---> # OAuth Credentials - AAD
auth0_username: "test_emx_stplanng_ehvypln_editor@latam.com"
auth1_username: "test_emx_stplanng_ehvypln_reader@latam.com"

Runtime Configuration (Cloud Run - if applicable to test execution, not the AUT)

The ERB files (.yaml.erb) in deploy/run/ suggest a configuration for Google Cloud Run, although this could be for infrastructure that supports test execution or related services, not the Cypress project itself deployed as an application.

  • deploy/run/runtime-config.yaml.erb:

    # min-instances: 0
    # max-instances: 5
    # execution-environment: gen2
    # ingress: all
    # concurrency: 5
    # timeout: 600
    # update-secrets: AUTH0_PASSWORD=auth0_password,AUTH1_PASSWORD=auth1_password
    # set-secrets: "DATABASE_PASSWORD=projects/831702928814/secrets/tmpl_arq_dev_lataminit-dev-cloudsql_passwd:latest"

    The update-secrets directive is crucial for managing AAD passwords (AUTH0_PASSWORD, AUTH1_PASSWORD) in the CI/CD environment.

  • deploy/run/environment.yaml.erb:

    ### ---> OAuth Credentials - AAD
    AUTH0_USERNAME: "<%= auth0_username %>"
    AUTH1_USERNAME: "<%= auth1_username %>"

    This template file is used to inject AAD usernames as environment variables into the runtime.

API Endpoints

This project focuses primarily on UI E2E tests, but also includes an example API test.

Pokémon GO API (Example)

Used as an example to demonstrate API testing capabilities with Cypress.

  • Feature File: cypress/e2e/features/api/api-PokemonGo.feature

    Feature: Pokemon GO API
    """
    Pokemon GO API
    """

    Scenario: Testing API - METHOD: GET - Endpoint: Abilities by ID
    When I send "ability/1"
    Then I validate answers you want to receive
  • Step Definition File: cypress/e2e/step_definitions/api/api-PokemonGo.cy.js

    /// <reference types="cypress" />

    import { When, Then } from "@badeball/cypress-cucumber-preprocessor";

    const url = "https://pokeapi.co/api/v2/";

    When("I send {string}", (endpoint) => {
    cy.request("GET", url + endpoint).as("response");
    });

    Then("I validate answers you want to receive", () => {
    cy.get("@response").its("status").should("equal", 200);

    cy.get("@response").its("body").should("have.property", "name", "stench"); // Example assertion
    });
MethodBase EndpointExample PathParametersAuthenticationExample Response (Status 200)
GEThttps://pokeapi.co/api/v2/ability/1Ability IDNot requiredJSON with ability details (e.g. { "name": "stench", ... })

Specific Components

Cypress

  • Main Configuration: cypress.config.js
    • Defines the preprocessor for Cucumber (@badeball/cypress-cucumber-preprocessor and @bahmutov/cypress-esbuild-preprocessor).
    • Configures the Mochawesome reporter (reporter: 'mochawesome').
    • Handles environment variables (env).
    • Sets patterns for specification files (specPattern).
    • Loads environment-specific baseUrl configurations from cypress/config/[entorno].config.json.
    • Filters browsers to use only Chromium-based ones.
    // Example cypress.config.js (excerpt)
    module.exports = {
    reporter: "mochawesome",
    // ... other configurations ...
    e2e: {
    env: {
    auth0_username: process.env.AUTH0_USERNAME,
    auth0_password: process.env.AUTH0_PASSWORD,
    // ...
    },
    specPattern: "cypress/e2e/features/*/*.feature",
    async setupNodeEvents(on, config) {
    // ... preprocessor and environment configuration ...
    const environmentName = config.env.environmentName || "cypress.dev";
    const environmentFileName = `./cypress/config/${environmentName}.config.json`;
    const settings = require(environmentFileName);
    if (settings.baseUrl) {
    config.baseUrl = settings.baseUrl;
    }
    return config;
    },
    },
    };
  • Cucumber Configuration: .cypress-cucumber-preprocessorrc.json
    • Defines the paths where step definition files are located.
    {
    "stepDefinitions": ["[filepath]/**/*/*.{js,ts}", "[filepath].{js,ts}", "cypress/e2e/step_definitions/*/*.{js,ts}"]
    }

Azure Active Directory (AAD) Authentication

  • Implementation: cypress/support/e2e.js

    • Defines a custom command cy.loginToAAD(username, password).
    • This command handles the Microsoft sign-in flow, interacting with login.microsoftonline.com.
    • Uses cy.session() to cache the authentication session and avoid repeated logins between tests.
    • Intercepts requests to add a custom header eMantto-Custom-Header.
    // cypress/support/e2e.js (excerpt)
    function loginViaAAD(username, password) {
    // ... AAD login logic ...
    cy.origin("login.microsoftonline.com" /* ... */);
    }

    Cypress.Commands.add("loginToAAD", (username, password) => {
    cy.session(
    `aad-${username}`,
    () => {
    /* ... */
    },
    {
    validate: () => {
    cy.getCookie("eMantto").should("exist");
    },
    cacheAcrossSpecs: true,
    }
    );
    });
  • Usage: In step definition files (e.g. cypress/e2e/step_definitions/ui/LoginPage.cy.js):

    import LoginAadPage from "../../../support/pages/login-aad-page";
    // ...
    Given("Previous authentication with AAD", () => {
    LoginAadPage.authADD; // Calls cy.loginToAAD with credentials from .env
    cy.visit("/");
    });

    login-aad-page.js abstracts the use of credentials from .env:

    // cypress/support/pages/login-aad-page.js
    class LoginAAD {
    get authADD() {
    cy.loginToAAD(Cypress.env("auth0_username"), Cypress.env("auth0_password"));
    }
    get authADD1() {
    // For another role/user
    cy.loginToAAD(Cypress.env("auth1_username"), Cypress.env("auth1_password"));
    }
    }
    export default new LoginAAD();

Page Object Model (POM)

The project uses the Page Object Model pattern to organize UI selectors and actions. Page Object files are located in cypress/support/pages/.

  • principal-page.js: Defines elements and methods for the application's main page.
  • login-page.js: May be for non-AAD login or generic login elements.
  • login-aad-page.js: Provides methods to invoke AAD login with different users/roles.

Mochawesome Reporter

  • Configuration: In cypress.config.js, reporter: 'mochawesome' and reporterOptions are specified.
    // cypress.config.js (excerpt)
    reporterOptions: {
    html: true,
    json: true,
    charts: true,
    overwrite: true,
    inlineAssets: true,
    embeddedScreenshots: true,
    reportDir: 'cypress/results',
    reportFilename: '`name`.json',
    },
  • Generation: Tests run with the -r mochawesome flag (or if it is the default reporter) generate JSON files in cypress/results/. The npm run cy:report script then merges them (mochawesome-merge) and generates an HTML report (marge). Screenshots and videos of failures are also captured and can be linked in the report.

Testing

This project is entirely dedicated to creating and running automated tests.

Test Types

  • UI Tests (End-to-End): Verify the complete application flow from the user's perspective, interacting with the graphical interface. Example: cypress/e2e/features/ui/LoginAAD.feature
  • API Tests: Verify specific backend service endpoints.
    • Example: cypress/e2e/features/api/api-PokemonGo.feature

Test Structure

  • Features: .feature files written in Gherkin, located in cypress/e2e/features/. They describe the expected system behavior.
  • Step Definitions: JavaScript files (.cy.js) located in cypress/e2e/step_definitions/. They map Gherkin steps to executable Cypress code.
  • Support Files:
    • cypress/support/commands.js: To define custom Cypress commands (although loginToAAD is in e2e.js).
    • cypress/support/e2e.js: Main support file, where commands.js is imported and global configurations or listeners can be defined. The loginToAAD logic is here.
    • cypress/support/pages/: Contains the Page Objects.
  • Fixtures: Static test data in JSON format, located in cypress/fixtures/ (e.g. example.json).

How to Run Tests

See the "Running Tests Locally" section under "Local Setup" for the npm run ... commands.

Test Reports

  • Tests generate individual JSON reports via Mochawesome in cypress/results/.
  • Execution videos are saved in cypress/videos/ (if video: true).
  • Failure screenshots are saved in cypress/screenshots/ (if screenshotOnRunFailure: true).
  • Use npm run cy:report to generate a consolidated HTML report that includes these artifacts.

Security Considerations

  • Credential Management:
    • Local: Sensitive credentials (such as AAD passwords) must be stored in a .env file at the project root. This file is included in .gitignore to prevent it from being committed to the repository.
    • CI/CD (Jenkins/Cloud Run): Credentials must NOT be hardcoded in code or versioned environment configuration files (deploy/env/*.yaml). They must be managed as secrets in the CI/CD system. - The deploy/run/runtime-config.yaml.erb file shows how secrets can be passed: update-secrets: AUTH0_PASSWORD=auth0_password,AUTH1_PASSWORD=auth1_password. CI/CD must provide the actual values for auth0_password and auth1_password.
  • Information Exposure: Ensure that generated reports and logs do not expose sensitive information. Mochawesome reporter options are configured for inlineAssets: true and embeddedScreenshots: true, which is convenient but bundles everything into the HTML. Consider policies for sharing these reports.
  • Custom Headers: The loginToAAD command adds eMantto-Custom-Header: eMx-e2e-testing-Cypress. Ensure this header is expected and handled appropriately by the application under test and does not introduce vulnerabilities.