Skip to content

Commit

Permalink
Merge branch 'develop' into organizationFilter
Browse files Browse the repository at this point in the history
  • Loading branch information
nihal467 authored Jan 9, 2025
2 parents def05a4 + 0592e63 commit f1f9b55
Show file tree
Hide file tree
Showing 30 changed files with 1,090 additions and 563 deletions.
2 changes: 1 addition & 1 deletion .cursorrules
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,4 @@ General Guidelines

# Testing Guidelines

For Cypress testing guidelines, refer to cypress/docs/cypress.md
For Cypress testing guidelines, refer to cypress/docs/*.md
5 changes: 2 additions & 3 deletions crowdin.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
files:
- source: /public/locale/{{lang}}.json
translation: /public/locale/%two_letters_code%/%original_file_name%
- source: public/locale/en.json
translation: /public/locale/%two_letters_code%.json
bundles:
- 2

32 changes: 32 additions & 0 deletions cypress/docs/best-practices.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Best Practices

## Test Independence
- Each test should be independent and isolated
- Clean up test data after tests
- Don't rely on the state from other tests

## API Testing
- Use cy.intercept() for API verification
- Use waitUntil() for API completion
- Avoid cy.wait() except for API responses

## Element Interaction
- Always verify element state before interaction
- Use data-cy attributes for selectors
- Verify button text before clicking

## Code Organization
- Keep tests focused and concise
- Follow AAA pattern (Arrange, Act, Assert)
- Use meaningful test descriptions

## Common Pitfalls to Avoid
- Redundant visibility checks with verifyAndClickElement
- Hardcoded values in page objects
- Unnecessary waits
- Test interdependencies

## Performance Considerations
- Minimize unnecessary API calls
- Use efficient selectors
- Batch similar operations
131 changes: 21 additions & 110 deletions cypress/docs/cypress.md
Original file line number Diff line number Diff line change
@@ -1,114 +1,25 @@
# Cypress Guidelines
# Cypress Testing Documentation

## File Structure
## Overview
This documentation covers the testing standards and patterns for our Cypress test suite.

```
cypress/
├── docs/
│ └── cypress.md
├── e2e/ # Test files grouped by modules
│ ├── patient/ # Patient module tests
│ │ ├── search.cy.ts
│ │ ├── create.cy.ts
│ │ └── edit.cy.ts
│ ├── facility/ # Facility module tests
│ │ ├── list.cy.ts
│ │ └── details.cy.ts
│ └── user/ # User module tests
│ ├── login.cy.ts
│ └── profile.cy.ts
├── fixtures/ # Test data files by module
│ ├── patient/
│ │ └── patient-data.json
│ └── facility/
│ └── facility-data.json
├── pageObject/ # Page Objects by module
│ ├── patient/
│ │ ├── SearchPage.ts
│ │ └── CreatePage.ts
│ ├── facility/
│ │ ├── ListPage.ts
│ │ └── DetailsPage.ts
│ └── utils/ # Common helpers and global functions
│ ├── CommonActions.ts # Shared actions across pages
│ ├── CommonAssertions.ts # Shared assertions
│ └── GlobalHelpers.ts # Platform-wide utility functions
├── support/ # Core support files
│ ├── commands.ts # Custom Cypress commands
│ ├── e2e.ts # e2e test configuration
│ └── index.ts # Main support file
└── tsconfig.json
```

## Support Files

- `commands.ts`: Custom Cypress commands and their TypeScript definitions
- `e2e.ts`: e2e specific configurations and imports
- `index.ts`: Main support file that loads commands and configurations

## Page Objects Utils

The `pageObjects/utils` folder contains:

- Common helper functions used across different page objects
- Global utility functions for platform-wide operations
- Shared assertions and verifications
- Reusable action patterns

## Module-based Organization

Each module (patient, facility, user, etc.) should have its own:

- Test files in `e2e/<module-name>/`
- Page Objects in `pageObjects/<module-name>/`
- Fixtures in `fixtures/<module-name>/`

This organization helps:

- Keep related tests and page objects together
- Maintain clear separation between module-specific and common utilities
- Enable better code reuse through common utilities
- Keep core support files focused and minimal
## Quick Links
- [File Structure and Organization](./file-structure.md)
- [Testing Patterns](./patterns.md)
- [Best Practices](./best-practices.md)

## Core Principles

- Create, use and modify Reusable Commands and Functions for Cypress as needed
- Provide Id for the elements using data-cy attributes
- When interacting with a button, verify the button is enabled and visible before interacting with it
- when interacting with a button, verify the text of the button is correct
- Use Page Object Model for Cypress
- Use built-in assertions for Cypress
- Use beforeEach, afterEach and all relevant hooks for Cypress on every test file

## File Naming Conventions

- Test files: `feature-name.cy.ts`
- Page Objects: `FeatureNamePage.ts`
- Custom Commands: `feature-name.ts`
- Fixtures: `feature-name-data.json`

## Storage Management

- Use cy.saveLocalStorage() and cy.restoreLocalStorage() for Cypress
- If we are using same element id to verify presence, interact and assert, make a reusable structure for it

## API Testing

- Use cy.intercept() for Cypress to verify API calls
- Use waitUntil() for Cypress to wait for API calls to complete
- Never use cy.wait() for Cypress except for API responses

## Best Practices

- Keep tests independent and isolated
- Use meaningful test descriptions
- Follow AAA pattern (Arrange, Act, Assert)
- Use fixtures for test data
- Implement custom commands for repetitive actions

### Code Editing Guidelines

- When suggesting code edits, provide only the relevant file and changes
- Don't create separate folders for each edit
- Keep the existing file structure intact
- Provide clear comments for what's being changed
- Create and use reusable commands and functions
- Use data-cy attributes for element identification
- Follow Page Object Model pattern
- Write independent and isolated tests
- Use TypeScript for better type safety

## Getting Started
1. Familiarize yourself with the file structure
2. Review the testing patterns
3. Follow the best practices
4. Use the provided examples as templates

## Support
For questions or clarifications, refer to the specific documentation sections or reach out to the team.
39 changes: 39 additions & 0 deletions cypress/docs/file-structure.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# File Structure and Organization

## Directory Structure
```
cypress/
├── docs/
│ ├── README.md
│ ├── file-structure.md
│ ├── patterns.md
│ └── best-practices.md
├── e2e/ # Test files grouped by modules
│ ├── patient/
│ ├── facility/
│ └── user/
├── fixtures/
├── pageObject/
└── support/
```

## Module Organization
Each module (patient, facility, user, etc.) should have:
- Test files in `e2e/<module-name>/`
- Page Object in `pageObject/<module-name>/`
- Fixtures in `fixtures/<module-name>/`

## File Naming Conventions
- Test files: `feature-name.cy.ts`
- Page Object: `FeatureNamePage.ts`
- Custom Commands: `feature-name.ts`
- Fixtures: `feature-name-data.json`

## Support Files
- `commands.ts`: Custom Cypress commands
- `e2e.ts`: e2e configurations
- `index.ts`: Main support file

## Storage Management
- Use cy.saveLocalStorage() and cy.restoreLocalStorage()
- Manage test data cleanup
50 changes: 50 additions & 0 deletions cypress/docs/patterns.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Testing Patterns

## Element Interaction
### Preferred Command Usage
```typescript
// Correct
cy.verifyAndClickElement('[data-cy="element"]', "Button Text");

// Avoid
cy.get('[data-cy="element"]').should('be.visible').click();
```

## Navigation Patterns
```typescript
// Good
navigateToOrganization(orgName: string) {
cy.verifyAndClickElement('[data-cy="organization-list"]', orgName);
}

navigateToFacilitiesList() {
cy.verifyAndClickElement('[data-testid="org-nav-facilities"]', "Facilities");
}
```

## Test Data Management
```typescript
// Constants for fixed values
const facilityType = "Primary Health Centre";

// Generator functions for dynamic data
const phoneNumber = generatePhoneNumber();
```

## Test Structure
```typescript
describe("Feature Name", () => {
const page = new PageObject();
const facilityType = "Primary Health Centre";
const testData = generateTestData();

beforeEach(() => {
// Setup
});

it("should perform action", () => {
page.navigateToOrganization("Kerala");
page.navigateToFacilitiesList();
});
});
```
58 changes: 58 additions & 0 deletions cypress/e2e/facility_spec/facility_creation.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { FacilityCreation } from "../../pageObject/facility/FacilityCreation";
import { generatePhoneNumber } from "../../utils/commonUtils";
import { generateFacilityData } from "../../utils/facilityData";

describe("Facility Management", () => {
const facilityPage = new FacilityCreation();
const facilityType = "Primary Health Centre";
const testFacility = generateFacilityData();
const phoneNumber = generatePhoneNumber();

beforeEach(() => {
cy.visit("/login");
cy.loginByApi("nurse");
});

it("Create a new facility using the admin role", () => {
facilityPage.navigateToOrganization("Kerala");
facilityPage.navigateToFacilitiesList();
facilityPage.clickAddFacility();

// Fill form
facilityPage.fillBasicDetails(
testFacility.name,
facilityType,
testFacility.description,
);

facilityPage.selectFeatures(testFacility.features);

facilityPage.fillContactDetails(
phoneNumber,
testFacility.pincode,
testFacility.address,
);

facilityPage.fillLocationDetails(
testFacility.coordinates.latitude,
testFacility.coordinates.longitude,
);

// Submit and verify
facilityPage.makePublicFacility();
facilityPage.submitFacilityCreationForm();
facilityPage.verifySuccessMessage();

// Search for the facility and verify in card
facilityPage.searchFacility(testFacility.name);
facilityPage.verifyFacilityNameInCard(testFacility.name);
});

it("Should show validation errors for required fields", () => {
facilityPage.navigateToOrganization("Kerala");
facilityPage.navigateToFacilitiesList();
facilityPage.clickAddFacility();
facilityPage.submitFacilityCreationForm();
facilityPage.verifyValidationErrors();
});
});
10 changes: 1 addition & 9 deletions cypress/e2e/login_spec/loginpage.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,11 @@ describe("Login Page", () => {
const loginPage = new LoginPage();

beforeEach(() => {
cy.clearLocalStorage();
cy.saveLocalStorage();
cy.visit("/login");
});

afterEach(() => {
cy.saveLocalStorage();
});

it("should successfully login with admin credentials", () => {
loginPage.interceptLogin();
loginPage.loginByRole("admin");
loginPage.verifyLoginResponse();
cy.loginByApi("staff");
cy.url().should("include", "/");
});

Expand Down
6 changes: 2 additions & 4 deletions cypress/e2e/patient_spec/patient_search.cy.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
import { LoginPage } from "pageObject/auth/LoginPage";

import { patientSearch } from "../../pageObject/Patients/PatientSearch";

describe("Patient Search", () => {
const loginPage = new LoginPage();
const TEST_PHONE = "9495031234";
const PATIENT_DETAILS = {
name: "Nihal",
Expand All @@ -12,7 +9,8 @@ describe("Patient Search", () => {
};

beforeEach(() => {
loginPage.loginByRole("nurse");
cy.visit("/login");
cy.loginByApi("nurse");
});

it("search patient with phone number and verifies details", () => {
Expand Down
6 changes: 5 additions & 1 deletion cypress/fixtures/users.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,9 @@
"nurse": {
"username": "nihal-nurse",
"password": "Test@123"
},
"staff": {
"username": "nihal-staff",
"password": "Test@123"
}
}
}
Loading

0 comments on commit f1f9b55

Please sign in to comment.