JavaScript · Cypress
NGO & donations with Cypress
Campaigns with progress bars, amount chips or a custom amount, one-time vs monthly, an optional fee top-up, PAN required at ₹2,000+ for an 80G certificate, anonymous and in-honour gifts, and pause/cancel for monthly giving.
App under test
💛 GiveHope
- URL
- /apps/donate
- Minimum
- ₹100
- PAN needed
- ₹2,000 and above
- Fee cover
- 2.5%
Scenarios to automate
Work top to bottom — each one adds a new technique.
- 1
Progress bars
Beginnerprogress-<id> is role=progressbar; read aria-valuenow and compare with raised-<id> / goal.
- 2
Chips vs custom
BeginnerTyping custom-amount clears the selected amount-* chip (aria-pressed=false) and vice versa.
- 3
Threshold field
Intermediatedonor-pan and pan-required only appear once the total reaches ₹2,000; the PAN format is validated.
- 4
Fee maths
Intermediatecover-fee adds 2.5%: ₹2,500 → fee-amount ₹62.50, donation-total ₹2,562.50.
- 5
Minimum amount
BeginnerA custom amount under ₹100 shows error-amount.
- 6
Conditional field
Beginnerin-honour (switch) reveals honoree-name, which is then required.
- 7
Recurring management
Intermediatepause-recurring → recurring-status Paused → resume/cancel via cancel-recurring-modal; year-total updates.
- 8
80G availability
IntermediateReceipts with a PAN show download-80g; smaller gifts show no-80g.
Sample Cypress suite
A working starting point that finds elements every way Cypress can — by role, label, text, id, name, CSS, XPath and data-testid — so you practice them all. Pick your language, switch to data-testid only to compare, or try your own in the Locator Playground.
Cypress runs inside the browser, so it only supports JavaScript and TypeScript — there is no Python, Java or C# version of Cypress. For those languages, see Selenium or Playwright.
// Uses the getByTestId custom command from the Cypress setup (cypress/support/commands.js).
// Locators in this suite: cy.contains ×3 · #id ×4 · [name] ×3 · [aria-label] ×1 · getByTestId ×14
describe('GiveHope — donations', () => {
it('sets up a monthly donation and pauses it', () => {
cy.visit('/apps/donate');
cy.contains('button', 'education').click();
cy.getByTestId('donate-c1').click();
cy.getByTestId('campaign-title').should('contain', 'Books for 500 rural classrooms');
cy.contains('button', 'Monthly').click();
cy.getByTestId('amount-2500').click();
cy.get('#cover-fee').check();
cy.getByTestId('fee-amount').should('contain', '₹62.50');
cy.getByTestId('donation-total').should('contain', '₹2,562.50');
cy.get('[name="donor-name"]').type('Amir Khan');
cy.get('#donor-email').type('amir@example.com');
cy.get('[name="donor-phone"]').type('9876543210');
cy.getByTestId('pan-required').should('be.visible');
cy.get('#donor-pan').type('ABCDE1234F');
cy.get('[aria-label="Give in honour of someone"]').click();
cy.get('[name="honoree-name"]').type('Grandma Fatima');
cy.getByTestId('pay-upi').click();
cy.get('#donate-upi').type('amir@okbank');
cy.getByTestId('donate-now').click();
cy.getByTestId('receipt-amount').should('contain', '₹2,562.50/month');
cy.getByTestId('download-80g').should('be.visible');
cy.getByTestId('manage-giving').click();
cy.getByTestId('recurring-status').should('contain', 'Active');
cy.getByTestId('year-total').should('contain', '₹30,750.00');
cy.contains('button', 'Pause').click();
cy.getByTestId('recurring-status').should('contain', 'Paused');
});
});