Files
MSE-SoftwEng/web-app/test.md
fastium c5efa10f1a test(web-app): add test end2end
- it implements a 1st version of it
2025-06-08 22:31:46 +02:00

7.7 KiB

End-to-End Testing Documentation for Home Monitor

Table of Contents

Introduction

End-to-End (E2E) testing verifies that the application functions correctly from a user's perspective by testing the complete application workflow. This document outlines the E2E testing approach for the Home Monitor application.

Goals of E2E Testing

  • Validate critical user flows function correctly
  • Ensure components work together as expected
  • Detect regression issues before production deployment
  • Verify application behavior in real-world scenarios

Testing Strategy

Home Monitor uses Cypress for E2E testing with two primary approaches:

  1. Mock Testing (Without Server): Fast, reliable tests using mocked DOM elements and data
  2. Real Environment Testing (With Server): Full application testing with a running development server

Mock vs. Real Testing Comparison

Aspect Mock Testing Real Environment Testing
Speed Very fast (< 1s per test) Slower (depends on app loading time)
Reliability Highly stable May be affected by server/network issues
Coverage Limited to structure and basic interactions Tests actual rendering and behaviors
Dependencies None (no server needed) Requires development server
Best for CI/CD, quick verification Final validation, regression testing

Test Environment Setup

Prerequisites

  • Node.js (v14+)
  • npm or yarn
  • Chrome browser (for visual testing)

Installation

# Install dependencies
cd project-softweng/web-app
npm install

Running Tests

Option 1: Tests with Mock Environment (No Server)

# Run all tests in headless mode
export CYPRESS_SKIP_SERVER_CHECK=true
npm run test:e2e

# Run specific test file
export CYPRESS_SKIP_SERVER_CHECK=true
npx cypress run --spec "tests/e2e/app.spec.ts"

Option 2: Tests with Real Application (Server Required)

Automated Script Method

# Use the automated script (starts server, runs tests, stops server)
./tests/e2e/run-e2e-tests.sh

Manual Method

  1. Start the development server:

    # Terminal 1
    npm run serve
    
  2. Run the tests:

    # Terminal 2
    # Headless mode
    npx cypress run --spec "tests/e2e/app.spec.ts"
    
    # Interactive mode
    npx cypress open
    

Interactive Mode (Development)

npm run cypress:open

This opens the Cypress Test Runner where you can:

  • Select individual tests to run
  • See test execution in real-time
  • Debug failing tests with time-travel debugging

Test Structure

Directory Structure

web-app/
├── tests/
│   ├── e2e/                   # E2E test files
│   │   ├── app.spec.ts        # Main application tests
│   │   └── run-e2e-tests.sh   # Script for running tests with server
│   └── support/               # Support files
│       ├── commands.ts        # Custom Cypress commands
│       └── e2e.ts             # Global setup for E2E tests
└── cypress.config.ts          # Cypress configuration

Test Files Organization

Each test file follows this structure:

  1. Setup: Import dependencies and set up the test environment
  2. Beforehooks: Prepare the application state before each test
  3. Test Cases: Individual test scenarios grouped by feature
  4. Helper Functions: Support functions for test cases

Test Cases Overview

The E2E test suite covers the following scenarios:

  1. Application Loading

    • Verify application loads with correct title
    • Confirm main layout sections are visible
  2. Control Panel Functionality

    • Verify control panel buttons are present
    • Test "Fetch Measurements" button works
    • Test "New Measurements" button works
  3. Filtering Controls

    • Test user selection dropdown
    • Test room selection dropdown
    • Test device selection dropdown
  4. Data Visualization

    • Verify chart displays correctly
    • Test chart updates when data changes
  5. Error Handling

    • Test error state display
    • Test empty data state display
  6. Responsive Design

    • Verify layout adapts to desktop viewport
    • Verify layout adapts to mobile viewport

Writing New Tests

Adding a New Test Case

  1. Identify the feature or flow to test
  2. Determine the expected behavior
  3. Add a new test case to the appropriate spec file:
it('should [describe expected behavior]', () => {
  // Setup any preconditions
  
  // Perform actions
  
  // Assert expected outcomes
});

Custom Commands

Custom commands are available to simplify test writing:

// Select an option from a multiselect dropdown
cy.selectMultiselectOption('user-select', 'user1');

// Wait for chart to load and be visible
cy.waitForChart();

// Check application loading state
cy.checkLoadingState(false);

API Mocking

Use Cypress's intercept feature to mock API responses:

// Mock GET request
cy.intercept('GET', '**/api/measurements*', {
  statusCode: 200,
  body: { 
    data: [
      { time: new Date(2023, 0, 1, 10, 0).getTime(), value: 22.5, type: 'temperature' }
    ]
  }
}).as('getMeasurements');

// Wait for the intercepted request
cy.wait('@getMeasurements');

Best Practices

  1. Test Independence

    • Each test should be able to run independently
    • Avoid dependencies between tests
    • Reset state between tests
  2. Selector Strategy

    • Prefer data attributes for test selectors (e.g., data-cy, data-testid)
    • Avoid using CSS classes that might change with styling updates
    • Establish a consistent selector naming convention
  3. Handling Asynchronous Operations

    • Use explicit waits rather than arbitrary timeouts
    • Wait for specific elements or network requests rather than fixed delays
    • Handle loading states appropriately
  4. Test Data Management

    • Use consistent test data
    • Mock external dependencies
    • Consider using fixtures for complex data structures
  5. Error Handling

    • Add proper error handling in tests
    • Use Cypress.on('uncaught:exception') for expected application errors

Troubleshooting

Common Issues and Solutions

Issue Solution
Tests fail with 401 errors Add Cypress.on('uncaught:exception', () => false) to handle authentication errors
Elements not found Increase timeouts or check selectors; ensure elements are in the DOM
Click actions failing Use { force: true } option if elements might be covered by overlays
Tests passing locally but failing in CI Check environment differences; ensure CI has all required dependencies
Timeouts on waiting for elements Increase defaultCommandTimeout in cypress.config.ts

Debugging Strategies

  1. Use Cypress's Debug Tools

    • Add .debug() to pause execution at a specific point
    • Use the time-travel debugger in interactive mode
  2. Add Logging

    • Use cy.log() to add informative messages in the test
    • Check browser console for application errors
  3. Visualize Test State

    • Enable screenshots and videos for failed tests
    • Use cy.screenshot() at critical points

References