Skip to content

Latest commit

 

History

History
273 lines (200 loc) · 7.32 KB

File metadata and controls

273 lines (200 loc) · 7.32 KB

Cypress Gmail API Testing

A minimal, shareable Cypress project for testing email workflows with Gmail through the Google API. This project is a compgnon to the article available at : https://www.clever-age.com/tester-les-emails-un-enjeu-cle-pour-la-qualite-logicielle/

📋 Overview

This project demonstrates how to:

  • Authenticate with Google OAuth2
  • Access Gmail via the Google API
  • Write Cypress tests that verify email content

Perfect for:

  • Testing email notifications in your workflow
  • Automating email-based test scenarios
  • Learning Cypress + Google API integration

🚀 Quick Start

Prerequisites

  • Node.js v16 or higher (download)
  • npm or yarn package manager
  • A Google Cloud Project with Gmail API enabled
  • A Gmail account for testing

📦 Installation

  1. Clone the repository:

    git clone https://github.com/YOUR_USERNAME/cypress-gmail-api-testing.git
    cd cypress-gmail-api-testing
  2. Install dependencies:

    npm install
  3. Set up Google OAuth credentials (see section below)


🔐 Google OAuth Setup

Step 1: Create a Google Cloud Project

  1. Go to Google Cloud Console
  2. Create a new project (name it cypress-gmail-testing)
  3. Enable the Gmail API:
    • Go to APIs & ServicesLibrary
    • Search for "Gmail API"
    • Click Enable

Step 2: Create OAuth2 Credentials

  1. Go to APIs & ServicesCredentials
  2. Click Create CredentialsOAuth 2.0 Client ID
  3. Select Application Type: Desktop app
  4. Download the JSON credentials file
  5. Rename to credentials.json and place in the project root

Your credentials.json structure should look like:

{
  "installed": {
    "client_id": "YOUR_CLIENT_ID.apps.googleusercontent.com",
    "client_secret": "YOUR_CLIENT_SECRET",
    "redirect_uris": ["http://localhost"],
    ...
  }
}

Step 3: Generate OAuth Token

Run the authentication script:

npx ts-node auth.ts

This will:

  1. Generate an authorization URL
  2. Open it in your browser
  3. Connect to the Gmail account and approve access to Gmail
  4. Copy the code in the url attribute ?code=XXXX
  5. Paste the code to the terminal
  6. It will generate a token.json file (contains your refresh token) in the project root

Your token.json structure sould look like this: { "access_token": "XXX", "refresh_token": "XXX", "scope": "https://www.googleapis.com/auth/gmail.readonly", "token_type": "Bearer", "expiry_date": 1767709000000 }

⚠️ Important: Never commit credentials.json or token.json to GitHub! (They're in .gitignore by default)


📝 Project Structure

cypress-gmail-api-testing/
├── src/
│   ├── auth.ts              # OAuth2 authentication script
│   └── utils.ts             # Helper functions for Gmail operations
├── cypress/
│   ├── e2e/
│   │   └── gmail.spec.ts    # Example Gmail tests
│   └── support/
│       ├── e2e.ts           # Cypress support configuration
│       └── commands.ts      # Custom Cypress commands
├── config/
│   └── credentials.example.json  # OAuth credentials template (shown for reference)
├── cypress.config.ts        # Cypress configuration with Gmail task
├── tsconfig.json            # TypeScript configuration
├── package.json             # Project dependencies
├── .gitignore               # Files to exclude from Git
├── .env.example             # Environment variables template
├── README.md                # This file
└── LICENSE                  # MIT License

🧪 How to use Gmail API testing

Use the getLastEmail task in one of your tests.

📧 Example Test

The project includes a sample test in cypress/e2e/gmail.spec.ts:

describe('Lecture Gmail', () => {
  it('Récupère le dernier email', () => {
    cy.task('getLastEmail').then((snippet) => {
      cy.log('Dernier mail :', snippet);
      expect(snippet).to.include(''); // Verify expected content
    });
  });
});

What it does:

  1. Calls the getLastEmail custom task (defined in cypress.config.ts)
  2. Fetches the most recent email from your Gmail inbox
  3. Logs the email snippet
  4. Verifies the content exists

🔧 Configuration

Cypress Configuration (cypress.config.ts)

  • Gmail Task: The getLastEmail task authenticates with Gmail and fetches the latest email snippet
  • Custom Tasks: Add more tasks via on('task', { ... })
  • Base URL: Modify as needed for your application

🔗 Custom Tasks & Helpers

Available Helper Functions (src/utils.ts)

  • initializeOAuth2Client() - Create OAuth2 client
  • setOAuth2Credentials() - Set credentials for client
  • loadCredentials() - Load credentials from file
  • loadTokens() - Load tokens from file

Example usage in tests:

import { loadCredentials, loadTokens } from '../src/utils';

const credentials = loadCredentials('credentials.json');
const tokens = loadTokens('token.json');

📌 Security Best Practices

Do:

  • Keep credentials.json and token.json in .gitignore
  • Use environment variables for sensitive data in CI/CD
  • Rotate OAuth tokens regularly
  • Restrict Gmail API scopes to what you need

Don't:

  • Commit credentials or tokens to GitHub
  • Share your credentials.json file
  • Use your personal Google account in CI/CD (create a service account)
  • Log sensitive data in test results

Adding Custom Commands

Define reusable commands in cypress/support/commands.ts:

Cypress.Commands.add('checkLastEmail', (expectedText) => {
  cy.task('getLastEmail').then((snippet) => {
    expect(snippet).to.include(expectedText);
  });
});

🐛 Troubleshooting

Issue: credentials.json not found

Solution: Ensure credentials.json is in the project root directory (not in the ressource/ folder)

Issue: Error: invalid_grant when running npx ts-node auth.ts

Solution: Your token has expired. Delete token.json and run npx ts-node auth.ts again

Issue: Gmail API not enabled

Solution:

  1. Go to Google Cloud Console
  2. Select your project
  3. Go to APIs & ServicesLibrary
  4. Search for "Gmail API" and click Enable

Issue: Tests timeout

Solution: Increase Cypress timeout in cypress.config.ts:

export default defineConfig({
  e2e: {
    requestTimeout: 10000,
    taskTimeout: 10000,
  },
});

📄 License

This project is licensed under the MIT License — see LICENSE file for details.


🤝 Contributing

Contributions are welcome! Please feel free to:

  1. Fork the repository
  2. Create a feature branch
  3. Submit a pull request

📞 Support

For issues or questions:


Happy Testing! 🎉