Writing Tests

How Cypress Tests Work

Cypress tests are written in JavaScript (or TypeScript) and follow a simple structure:

  1. Test Suite: Groups related tests using the describe function.
  2. Individual Tests: Each test is written using the it function.
  3. Commands: Cypress commands perform actions (e.g., click buttons, type text).
  4. Assertions: Verify that the application behaves correctly.

Basic Test Syntax

Here's a basic test:

Javascript
Copy
describe('My Application Tests', () => {
  it('should load the homepage', () => {
    cy.visit('https://example.com');       // Opens the website
    cy.contains('Example Domain');        // Checks for text on the page
  });
});
  • describe: Groups tests together under a label.
  • it: Defines an individual test case.
  • cy: The Cypress object, used to interact with the application.

Selecting Elements in Cypress

To interact with web elements, you need to select them. Cypress uses CSS selectors for this:

1. By Element Tag:

Javascript
Copy
cy.get('button'); // Selects all <button> elements

By Class Name:

Javascript
Copy
cy.get('.btn-primary'); // Selects elements with the class "btn-primary"

By ID:

Javascript
Copy
cy.get('#username'); // Selects the element with the ID "username"

By Attribute:

Javascript
Copy
cy.get('input[name="email"]'); // Selects input with name="email"

Interacting with Elements

Cypress commands allow you to interact with elements, such as clicking buttons or typing text.

1. Clicking a Button:

Javascript
Copy
cy.get('button#login').click(); // Clicks the "Login" button

2. Typing in Input Fields:

Javascript
Copy
cy.get('input[name="email"]').type('user@example.com');

3. Clearing Input Fields:

Javascript
Copy
cy.get('input[name="email"]').clear();

4. Selecting from a Dropdown:

Javascript
Copy
cy.get('select').select('Option 1');

Writing Assertions

Assertions verify that the application behaves as expected. Cypress comes with built-in assertions using Chai.

1. Check Text on Page:

Javascript
Copy
cy.contains('Welcome').should('be.visible'); // Checks if "Welcome" is visible

2. Check URL:

Javascript
Copy
cy.url().should('include', '/dashboard'); // Checks if the URL contains "/dashboard"

3. Check Element State:

Javascript
Copy
cy.get('button#submit').should('be.disabled'); // Checks if the button is disabled

4. Check Element Count:

Javascript
Copy
cy.get('.item').should('have.length', 5); // Checks if there are 5 elements with the "item" class

Combining Commands and Assertions

Here's an example of combining multiple commands and assertions in a single test:

Javascript
Copy
describe('Login Page Tests', () => {
  it('should allow users to log in', () => {
    cy.visit('https://example.com/login'); // Open the login page
    cy.get('input[name="username"]').type('testUser'); // Enter username
    cy.get('input[name="password"]').type('password123'); // Enter password
    cy.get('button[type="submit"]').click(); // Click login button
    cy.url().should('include', '/dashboard'); // Verify redirection to the dashboard
    cy.contains('Welcome, testUser').should('be.visible'); // Check welcome message
  });
});

Handling Dynamic Content

Web pages often load data dynamically, which requires waiting for the content to appear. Cypress automatically waits for elements to load, but you can use .should() for specific checks.

Example:

Javascript
Copy
cy.get('.notification').should('contain', 'Login successful'); // Waits for the notification

Using Cypress Aliases for Reusability

If you need to reuse elements, you can assign them aliases using .as():

Javascript
Copy
cy.get('input[name="username"]').as('usernameField');
cy.get('@usernameField').type('testUser'); // Reuses the alias