Here, I have prepared a Cypress exercise for a distinct case when we want to interact with a specific button on the page. I’ll try to be as concise and straightforward as possible and explain everything step by step, just as I do in my everyday practice.
Task description
Our main task is setting up Cypress to click on a specific (or unique) button on a page. Here is the link to the page that we gonna test:
Home
By “specific button” on the given page, we mean the first Learn More button on the page. This task request is specific because multiple buttons on the page have identical copy (Learn More). And, as we will see, that is not the only thing that is identical to other elements on the page. Here is the component that we are referring to:
How do you identify a unique button on a page?
To set Cypress so that it finds a unique button on the page, we have to give it proper commands. Namely, before doing that, we must clarify something related to testing buttons. We can’t just treat them as plain text. Cypress won’t identify it that way as a button. So a command such as the following won’t work properly:
cy.contains(‘Learn More’).click()
We gotta be more specific than that.
Basically, you can target an element on the page in many ways. It can either be the element ID or the class name. Also, it can be a specific class, such as the <span> class. To determine which of these is given for a particular element, we have to follow these steps:
- Find the element you want to test.
- Right-click on it.
- Select the Inspect option.
- Identify the element.
In my example, the element looks like this:
<span class=”uagb-inline-editing”>Learn More</span>
Let’s deconstruct it for better comprehension
The “Learn More” button is represented by an <span>
element with the class name uagb-inline-editing
. Now, let me show you how to implement this in a Cypress code:
cy.get(‘span.uagb-inline-editing’).click()
NOTE: If the component would be represented by a plain <class> element, then it could be implemented in the Cypress code with a dot (without the “span” part). Here is an example:
cy.get(‘.uagb-inline-editing’).click()
<span>
: This is an HTML element used to group inline elements. It’s typically used when applying styles or manipulating content within a specific section of text.class="uagb-inline-editing"
: This is an attribute of the<span>
element. Theclass
attribute is used to assign one or more classes to an HTML element, which can then be targeted by CSS or JavaScript for styling or functionality purposes. In this case, the classuagb-inline-editing
is assigned to the<span>
element.Learn More
: This is the content enclosed within the<span>
element. It’s simply the text “Learn More” that will be displayed on the webpage.
So, this HTML snippet represents an <span> element with the class uagb-inline-editing, containing the text “Learn More.” It’s likely used as a button or link on the webpage, and you can target it with CSS or JavaScript based on its class for styling or interaction purposes.
Since we have to target the unique Learn More button directly, we use the cy.get Cypress command.
What if the class name is not unique?
Now, here comes the fun part of this exercise. I have run the code in Cypress following the guides listed above. The code looks like this:
describe('Testing Learn More button', () => {
it('Clicks on the "Learn More" button', () => {
// Visit the website
cy.visit('https://notoolsnocraft.tech/')
// Find and click on the "Learn More" button
cy.get('span.uagb-inline-editing').click()
})
})
Cypress responded with the following error:
“cy.click()
can only be called on a single element. Your subject contained 5 elements. Pass{ multiple: true }
if you want to serially click each element.“
Identifying all page elements with the same class name
Cypress is telling us that there are multiple (5) elements on the page using the same class name. This means that our request is not well defined. We can test this manually by going back to the inspect mode. Follow these steps:
- Right-click on the Learn More button.
- Click on Inspect.
- Copy the class name of the element. In this case, it’s uagb-inline-editing.
- Ctrl + F
- Paste the class name in the search bar and check how many elements on the page use the same class name.
- Determine which one is in order the class name of our target button among identical class names on the page.
The inspection results show that our target button’s class name is the second among the 5 with identical names. We need a unique way to identify this one button. It must be defined clearly in our Cypress code. We will do that using a .eq filtering method.
.eq()
: This filtering method selects an element at a specific index from the list of elements retrieved by the previous command. Indexes in JavaScript (and in most programming languages) start at 0, so .eq(1) selects the second element in the list.
If you use .eq(0)
, Cypress will select the first <span>
element on the page with the class uagb-inline-editing
..eq(1)
selects the second <span>
element with that class, which is helpful if there are multiple elements with the same class on the page, and you must interact with one beyond the first.
The final version of the code
Since our target button is the 2nd among the ones with identical class names, we must insert .eq(1) in our code. Let’s do it:
describe('Testing Learn More button', () => {
it('Clicks on the "Learn More" button', () => {
// Visit the website
cy.visit('https://notoolsnocraft.tech/')
// Find and click on the "Learn More" button
cy.get('span.uagb-inline-editing').eq(1).click()
})
})
Cypress just showed the results I wanted! It found the target button, clicked on it, and loaded the desired page.