DEV Community

mohamed Said Ibrahim
mohamed Said Ibrahim

Posted on • Originally published at Medium

# How to Automate a Real-World Container Charter Platform with Cypress: Best Practices for QA…

How to Automate a Real-World Container Charter Platform with Cypress: Best Practices for QA Engineers

Tags: Cypress, End-to-End Testing, QA Automation, Container Charter Platform, Dashboard Testing, JavaScript, CI/CD, Test Best Practices


Introduction

This article provides a complete guide to automating a container charter platform using Cypress, a leading JavaScript end-to-end testing framework. The platform includes a shipping logistics dashboard with features like route tracking, dynamic pricing, statistical charts, and port listings. We’ll explore how to build a scalable, maintainable Cypress testing suite using best practices, including POM, API mocking, custom commands, and CI integration.


Why Cypress Is Ideal for This Platform

Cypress is perfectly suited for modern web apps because:

  • It runs directly in the browser, providing native access to elements.
  • It supports real-time reloads and instant feedback.
  • It offers powerful tools for network stubbing and mocking.
  • It integrates smoothly with CI pipelines.

For a platform reliant on real-time data and API-driven UIs like this container charter system, Cypress ensures robustness, speed, and maintainability.


Understanding the Platform

Key modules to test:

Routes: Origin–destination containers, ETA predictions, live route mapping.

Prices: Dynamic price updates per container line or location.

Statistics: Charts showing shipping trends, volume, and delays.

Ports: Real-time active port listings with filtering options.


Cypress Setup and Project Structure

Install Cypress:

npm init -y  
npm install cypress --save-dev  
npx cypress open  
Enter fullscreen mode Exit fullscreen mode

Recommended directory structure:

cypress/  
├── fixtures/ # Test data (e.g., mock responses)  
├── integration/  
│ └── dashboard/ # Test files for dashboard modules  
├── pages/ # Page Object files (POM pattern)  
├── support/  
│ ├── commands.js # Custom Cypress commands  
│ └── index.js  
cypress.config.js  
Enter fullscreen mode Exit fullscreen mode

Using Page Object Model (POM)

Encapsulate dashboard selectors and actions in pages/DashboardPage.js:

class DashboardPage {  
  visit() {  
  cy.visit('/dashboard');  
  }  
  getRouteInfo() {  
  return cy.get('\[data-testid="route-info"\]');  
  }  
  getPriceSection() {  
  return cy.get('\[data-testid="price-section"\]');  
  }  
  getStatsChart() {  
  return cy.get('\[data-testid="stats-chart"\]');  
  }  
  getPortList() {  
  return cy.get('\[data-testid="port-list"\] li');  
  }  
}

export default new DashboardPage();  
Enter fullscreen mode Exit fullscreen mode

Writing Clean Functional Tests

import DashboardPage from '../../pages/DashboardPage';

describe('Dashboard UI Tests', () => {  
  beforeEach(() => {  
  cy.loginAs('admin');  
  DashboardPage.visit();  
  });

  it('Displays correct route information', () => {  
  DashboardPage.getRouteInfo().should('contain', 'Hamburg').and('contain', 'Shanghai');  
  });

  it('Displays valid pricing data', () => {  
  DashboardPage.getPriceSection().invoke('text').then(price => {  
  expect(parseFloat(price.replace('', ''))).to.be.gt(0);  
  });  
  });

  it('Renders the statistics chart', () => {  
  DashboardPage.getStatsChart().should('be.visible');  
  });

  it('Shows a list of available ports', () => {  
  DashboardPage.getPortList().should('have.length.greaterThan', 3);  
  });  
});  
Enter fullscreen mode Exit fullscreen mode

Mocking APIs for Speed & Reliability

Avoid flaky tests and gain speed using cy.intercept()\:

cy.intercept('GET', '/api/dashboard/prices', {  
  statusCode: 200,  
  body: { currentPrice: 1800 }  
}).as('mockPrice');  
Enter fullscreen mode Exit fullscreen mode

Use this before tests that rely on /prices\ data.


Custom Cypress Commands

Define reusable login or setup tasks in support/commands.js\:

Cypress.Commands.add('loginAs', (role) => {  
  const users = {  
  admin: { username: 'admin', password: 'admin123' },  
  viewer: { username: 'viewer', password: 'viewer123' }  
  };

  cy.visit('/login');  
  cy.get('#username').type(users\[role\].username);  
  cy.get('#password').type(users\[role\].password);  
  cy.get('button\[type="submit"\]').click();  
});  
Enter fullscreen mode Exit fullscreen mode

Handling Edge Cases and Fallback UI

Ensure the dashboard handles API failures gracefully:

cy.intercept('GET', '/api/dashboard/stats', { statusCode: 500 }).as('failStats');  
cy.visit('/dashboard');  
cy.get('\[data-testid="stats-error"\]')  
  .should('be.visible')  
  .and('contain', 'Unable to load statistics');  
Enter fullscreen mode Exit fullscreen mode

CI/CD Integration with GitHub Actions

Enable Cypress tests to run on every pull request:

jobs:  
  e2e-tests:  
  runs-on: ubuntu-latest  
  steps:  
  - uses: actions/checkout@v2  
  - uses: cypress-io/github-action@v5  
  with:  
  start: npm start  
  wait-on: 'http://localhost:3000'  
  wait-on-timeout: 120  
  command: npm run test:e2e  
Enter fullscreen mode Exit fullscreen mode

Also add reporting tools like **Mochawesome** or **Allure**:

npx cypress run --reporter mochawesome  
Enter fullscreen mode Exit fullscreen mode

Final Thoughts

If you’re working on a data-driven dashboard or shipping application, Cypress can dramatically improve your test quality and speed to release.


About the Author

I’m Mohamed, a passionate QA Automation Engineer specializing in modern web automation with Cypress, Selenium, and Playwright. I share weekly articles on practical QA strategies and tools.

✅ Follow me on Medium for more Cypress insights

✅ Let’s connect on [LinkedIn](https://www.linkedin.com/in/your-profile)

Happy Testing! 🚀

View original.

Exported from Medium on October 2, 2025.

Top comments (0)