Cypress Workshop Part 5: Elements manipulation - Button, Input, Radio Button, Checkbox
Tags: qa, testing, automation, cypress
Published: 2023-05-20 15:16:55

## Button Actions

Button actions - clicks, are one of the most used in UI web automation. In order to write tests, you will have to learn how to click on different types of buttons, so let’s cover the most popular ones. 

Learn more about button actions: 
:information_source: [click](https://docs.cypress.io/api/commands/click#Syntax)
:information_source: [interacting with elements](https://docs.cypress.io/guides/core-concepts/interacting-with-elements#What-you-ll-learn)

1: Create new folder under `e2e` and call it for example `elements_manipulation`. Under that folder, create new test file and call it for example `button.cy.js`.

2: Write the following test inside: 

```javascript
/// <reference types="Cypress" />

describe('Buttons: Button actions', () => {
  before('Navigate to buttons page', () => {
    cy.visit('/buttons');
  });

  it('Check different button actions', () => {
    // Double click on button
    cy.get('#doubleClickBtn').dblclick();
    cy.contains('You have done a double click').should('be.visible');

    // Right-click on button
    cy.get('#rightClickBtn').rightclick();
    cy.contains('You have done a right click').should('be.visible');

    // Click on button
    cy.get('[class="btn btn-primary"]').then((buttons) => {
      cy.wrap(buttons).eq(2).click();
      cy.contains('You have done a dynamic click').should('be.visible');
    });
  });
});
```
**Code explanation:** 

We are visiting our app’s page dedicated for testing buttons ([page](https://demoqa.com/buttons)). We are using `before` hook for that, since we only have 1 test.

Inside the test body, we can see 3 examples: how to perform double click on the button, how to perform right click and a single dynamic click.

- Double click: we are locating our button and performing double click action `dblclick()` and after that we are performing assertion to confirm that proper text is visible after we double-clicked on the button. 

- Right-click: we are locating our button and performing right click action `rightclick()` and after that we are performing assertion to confirm that proper text is visible after we right-clicked on the button. 

- Single click: we are locating our button and performing single click action `click()` and after that we are performing assertion to confirm that proper text is visible after we clicked on the button. You will notice that for this button we didn’t have a unique `id`, compared to others, so we wrapped the class it belongs to into a JQuery object, and we selected the third element in that class (our subject button).

3: Execute the test: Open cypress CLI and run this test. Have a look at the logs. 

![Button actions test - execution results](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7phqwsqfpqdsyh7q9t5c.png)

## Input Actions

Inputs are also very common web elements you will have to interact with, so let’s write one test to see how we can do it.

Learn more about input actions: 
:information_source: [type](https://docs.cypress.io/api/commands/type)
:information_source: [clear](https://docs.cypress.io/api/commands/clear#Syntax)

1: Create new test file under `e2e/elements_manipulation` and call it for example `input.cy.js`. Write the following test inside. 

```javascript
/// <reference types="Cypress" />

describe('Inputs: Input actions', () => {
  before('Navigate to input page', () => {
    cy.visit('/text-box');
  });

  it('Check different input actions', () => {
    // Fill the form details
    cy.get('#userName').type('Arya Stark');
    cy.get('#userEmail').type('noone@example.com');
    cy.get('#currentAddress').type('Braavos, East of Westeros');
    cy.get('#permanentAddress').type('Winterfell,{enter}Kingdom of the North,{enter}Westeros');

    // Submit form and check if expected text is dispalyed
    cy.get('#submit').click();

    // Example assertions - Verify that we got correct output for name and email
    cy.get('#name').contains('Arya Stark');
    cy.get('#email').contains('noone@example.com');

    // Edit username input field, submit form and assert that username is changed
    cy.get('#userName').clear().type('Jon Snow');
    cy.get('#submit').click();
    cy.get('#name').contains('Jon Snow');
  });
});

```

**Code explanation:**

We are visiting our app’s page dedicated for testing inputs ([text-box](https://demoqa.com/text-box)). We are using `before` hook for that, since we only have 1 test.

As you can see, on that page, we have several input fields and one submit button. 

First, we should fill this form. We are entering: username, email, current address and permanent address. We are using `type()` cypress function to write the text. In the permanent address, you will notice that we are also simulating that the user pressed `ENTER` key with `{enter}` option, in order to write their address in multiple lines. 

Then, we are clicking on submit button to submit form. Due to limitation of this app (button is of `type="button"` and not `"submit"` , we can't use native cypress option that is recommended for submitting forms ([read more here](https://docs.cypress.io/api/commands/submit#Syntax) )

After we submitted the form, we are doing assertions to check if we got our expected output, for example in this case let’s say we are interested to check if we got text output of name and email correctly. 

Next, let’s say we want to re-submit the form with some different values of username. So, we are using cypress function `clear()` to delete previously added value of username, and we are typing new one. 

Lastly, we are re-submitting the form, and we are checking if the name is updated to the new one. 

2: Execute the test: Open Cypress CLI and run this test. Have a look at the logs. 

![Input actions test - execution results](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xidhn7u37okqseoqufwe.png)

## Radio Button Actions

Radio buttons are another popular element in modern web application. Let’s see how we can test them. 

:information_source: Learn more about radio button actions: 
[check](https://docs.cypress.io/api/commands/check)

1: Create a new test file under `e2e/elements_manipulation` and call it, for example, `radioButton.cy.js`. Write the following test inside. 

```javascript
/// <reference types="Cypress" />

describe('Radio Buttons: Radio Button actions', () => {
  before('Navigate to radio buttons page', () => {
    cy.visit('/radio-button');
  });

  it('Check different radio button actions', () => {
    cy.get('.custom-radio')
      .find('[type="radio"]')
      .then((radio) => {
        /* Get all radio buttons, select first one and verify that it is 
         checked and that we got confirmation text */
        cy.wrap(radio).first().check({ force: true }).should('be.checked');
        cy.contains('.text-success', 'Yes');

        /* Get all radio buttons, select second one and verify that it is 
         checked and that we got confirmation text */
        cy.wrap(radio).eq(1).check({ force: true }).should('be.checked');
        cy.contains('.text-success', 'Impressive');

        // Verify that first radio button is no longer checked
        cy.wrap(radio).eq(0).should('not.be.checked');

        // Verify that third button is disabled
        cy.wrap(radio).eq(2).should('be.disabled');
      });
  });
});

```

**Code explanation:** 

We are visiting our app’s page dedicated for testing radio buttons ([page](https://demoqa.com/radio-button)). We are using `before` hook for that, since we only have 1 test.

Furthermore, we are trying to find all radio buttons on the page, by searching class and type. 

Then, we are creating JQuery object, wrapping up all our radio buttons.

We are first selecting the first radio button with cypress function `.first()` (note: this is the same as if we wrote index `.eq(0)`). We are forcing this action because another element in the DOM is hovering ours (`{ force: true }`) and we are verifying that our radio button is checked and expected text is displayed.

Then, we are selecting second radio button with second index `.eq(1)` and we are performing the same checks as in previous example, except we added now new assertion - to check if previous radio button is not selected any more. 

Then, we are verifying that the third radio button is disabled - not clickable. 

:information_source: In real-life projects, it often happens that radio buttons, checkboxes, and similar - don’t have unique IDs. That is why this test was written without utilizing provided IDs, and searching elements by other properties (homework note: you can practice and write this test in another way, try to use provided IDs for radio buttons).

2: Execute the test: Open Cypress CLI and run this test. Have a look at the logs. 


![Radio Button actions test - execution results](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8ivs3m7g3tij7kmu8ky1.png)

## Checkbox Actions

Checkbox actions are very similar to radio buttons, except you can choose multiple checkboxes, compared to radio buttons where it is usually a single choice. Let’s try. 

Learn more about checkbox actions: 
:information_source: [check](https://docs.cypress.io/api/commands/check)
:information_source: [uncheck](https://docs.cypress.io/api/commands/uncheck#Syntax)

1: Create a new test file under `e2e/elements_manipulation` and call it, for example, `checkbox.cy.js`. Write the following test inside. 

```javascript
/// <reference types="Cypress" />

describe('Checkboxes: Checkbox actions', () => {
  before('Navigate to checkbox page', () => {
    cy.visit('/checkbox');
  });

  it('Check different checkbox actions', () => {
    // Open home dropdown
    cy.get('button[aria-label="Toggle"]').click();

    // Open Desktop dropdown
    cy.get('button[aria-label="Toggle"]').eq(1).click();

    // Get all checkboxes, select Desktop folder and everything under desktop folder.
    cy.get('[type="checkbox"]').then((checkbox) => {
      cy.wrap(checkbox).eq(1).check({ force: true }).should('be.checked');
      // Verify that correct text is displayed for chosen options
      cy.contains('.text-success', 'desktop');
      cy.contains('.text-success', 'notes');
      cy.contains('.text-success', 'commands');

      // Uncheck notes
      cy.wrap(checkbox).eq(2).uncheck({ force: true }).should('not.be.checked');
      cy.contains('.text-success', 'notes').should('not.exist');

      /* Select every checkbox in the tree, uncheck Notes and then select Notes by 
          not specifying exact Notes checkbox index */
      cy.wrap(checkbox).eq(0).check({ force: true }).should('be.checked');
      cy.wrap(checkbox).eq(2).uncheck({ force: true }).should('not.be.checked');

      cy.wrap(checkbox).check({ force: true }).should('be.checked');
      cy.contains('.text-success', 'notes');
    });
  });
});

```
**Code explanation:**

We are visiting our app’s page dedicated for testing radio buttons ([page](https://demoqa.com/checkbox)). We are using `before` hook for that, since we only have 1 test.

First, we are clicking on Home arrow element to expand the dropdown tree. 

Then we are clicking on Desktop arrow to expand its children. 

As you can see in the DOM, these checkboxes we are seeing, don’t have unique IDs. So, we are searching for all elements of `type="checkbox"` , we are creating JQuery object and then we are wrapping those into single elements we want to use. 

First, we are clicking on second checkbox which represents Desktop folder. Then we are clicking on the checkbox to select everything under Desktop folder. We are asserting that parent checkbox of Desktop is checked, and we are asserting that we got text output for Desktop and its children folders - Notes and Commands.

Then, we are unchecking Notes checkbox, we are asserting that it is now unchecked and “notes” output text is not there anymore. For this we used `uncheck()` function. Why? Because `check()` function is only to check something, and if you want to uncheck something, you need to use `uncheck()` or  `click()`.

Next, we want to select the entire Home tree and all children checkboxes. But, in order to demonstrate the case when we don’t need specified index for checkbox, let's uncheck Notes (line: 30). On the line 32, you can see that we didn’t specify which checkbox to check next, but you can see that Notes have been checked (line: 32, 33). How did Cypress knew which one to check? Because `check()` function will always verify all available checkboxes on the page, get their state, and if there is only one left unchecked, it will select that one. If there are more, you will have to specify which one you want to check, as we did in previous examples. 

2: Execute the test: Open cypress CLI and run this test. Take a look at the logs. 

![Checkbox actions test - execution results](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2ywac4f872jkv4acxa8p.png)

## HOMEWORK:

Add more scenarios that you can think of, for clicking on buttons, filling input fields, checking different checkboxes and radio buttons on the same app pages we used for above explanations. 

Don’t forget to push everything you did today on Github :wink: Remember git commands?

`git add .`

`git commit -am "add: button, radio button, input, checkbox tests"`

`git push`

<img width="100%" style="width:100%" src="https://media1.giphy.com/media/dsHZLWYu5SC6k/giphy.gif">

KEEP LEARNING, SEE YOU IN LESSON 6!

[Completed code for this lesson](https://github.com/ViktorijaFilipov/cypress-workshop/tree/main/LESSON_5)

If you have learned something new, feel free to support my work by buying me a coffee :coffee:

[![Buy Me A Coffee][2]][1]

[1]: https://www.buymeacoffee.com/viktorija3141
[2]: https://cdn.buymeacoffee.com/buttons/default-black.png