<linearGradient id="sl-pl-bubble-svg-grad01" linear-gradient(90deg, #ff8c59, #ffb37f 24%, #a3bf5f 49%, #7ca63a 75%, #527f32)
Loading ...

QA essentials

Your go-to quality assurance source

Cypress Reusability: Custom Commands, BaseUrl and POM

In the previous article of Cypress learning series we have created a test for user registration. During this test we explained the concepts of working with hooks, finding elements and some functions for interacting with them, checking response status and aliasing. In this article we will improve what we did the last time. We will explore the concepts of BaseUrl, Page Object Model (POM) and custom commands in Cypress. All of these provide a higher level of reusability of our test framework.

BaseUrl helps us switch testing environments

In certain cases, we run our tests in different environments like test, staging, pre-production, etc. All of these presumably have different URLs and hardcoding those URLs in tests makes them difficult to maintain. Or let’s imagine that DevOps migrate our test environments to a new infrastructure and parts of the base URL change. We would have to make that change manually in every place where we mention this URL which can be hundreds or even thousands of places. The best option would be to have a single place where we enter the URL of the test environment so in case of changes we need to make the change in just one place.

This is exactly what baseURL property helps us do. Just to remember, we had in our tests the URL for opening the website under test and also we added the same in the intercept functions.

custom commands in cypress

We can take this entire URL https://ecommerce-playground.lambdatest.io and store it as BaseURL. Normally, we would do that in cypress.config.js file which should look like this now:

baseUrl cypress config custom commands in cypress

What we need to do next is to apply the changes from this setting in our tests. To do that, we simply delete this part of the URL from all references.

applied baseUrl in the tests

If we run the test now with these changes, nothing should change. The test should still pass without any differences. Remember to remove the old URL from every reference in the test. If you need to use it in different places just copy the entire URL of the page you need and then delete the base part.

BaseURL best practice

It is possible to get the baseUrl from Cypress.config function although it feels redundant and just adds complexity to your tests.

cy.visit(Cypress.config('baseUrl'));

We have already seen that cy.visit command works with passing just / as an argument. Using baseUrl like above example is too much and does not provide any advantage.

Page Object Model in Cypress

Page Object Model is the most commonly used model in custom frameworks for automated test execution. It is very good for beginners to understand concept of abstraction. Although it has some limitations it still is the most widely used model among Quality Engineers. The main point in POM is to have functions and locators for elements on a single page grouped in a class and then those functions can be reused. We will explore a bit different POM with Javascript classless objects.

As you have noticed in our tests we repeat the selectors in each test because we interact with the same elements. In case of change in for example username selector in HTML we would have to change the selector everywhere manually. If we add these selectors in Javascript object and import that object in our test file we would be able to use the items from that object in our tests. Most importantly in case of any changes in HTML we need to make the change in one place only. Second advantage of such behavior is we can make the selectors more readable and therefore debugging would be a lot easier.

POM implementation

Let’s first create a new folder called Selectors and in it a Javascript file called registrationPageSelectors.js

javascript object selectors file

We will create a Javascript object in it and add all the selectors from registration page.

registration page selectors

In the next steps we need to import this file in our userRegistration.cy.js test file and replace all the raw selectors with object properties. This needs to be added at the top of the file.

import registrationPageSelectors from "../../../selectors/registrationPageSelectors";
selectors replaced with object properties

Now it looks a lot cleaner and easier to understand what line is for which element. Remember that we need to this also for the elements from the beforeEach block where we open the hover over the button and click on Registration button. Running the test again should do exactly the same like previously.

Custom commands in Cypress

Cypress provides us with ability to create functions for those actions we often use. We can extract a snippet of code in a custom command and reuse it whenever we need. Custom commands are stored in command.js file in Support folder which was auto-generated when we installed Cypress.

custom commands in Cypress

In this file we have auto-generated commands which are commented out and we can create our commands but also we can override existing Cypress commands. We want to create a command for filling out the form which would take an object with information needed for registration as an argument. In general we can create this command with completing the entire form and clicking on submit but there is a case in our tests which we cannot handle with such custom command. That is the case for checking sending of the form when privacy policy is not accepted. We would have to implement a conditional logic in the command for selecting and deselecting the privacy policy. Such conditional logic is not recommended.

For storing the objects with data we will create a new Javascript file. Add new folder in Cypress folder with name “data” and add new file in it called userRegistrationData.js. In this file we will add the objects for each of the cases we need to test.

user data custom commands in cypress

Create new command

Let’s start with creating new command. Open commands.js file and create new command with name completeRegistrationForm. As a parameter we expect the object with user data. We can put the parameters for each of the fields but there are too many of them to keep the command readable. Therefore it is better to create an object with properties matching each of the fields needed to populate. Like this we have just one parameter for this command.

custom commands in cypress

Finally, let’s apply this command to our test. We need to apply this command in every it block where applicable. Here is an example for one of the blocks.

custom commands in cypress

As you can see we replaced the large number of lines in the test with one line command. This command is reusable and we use it with different arguments in different it blocks. Once again, running the test should not show any different results.

Conclusion

In this article we tackled optimization of our tests by making them more readable, less prone to high maintenance costs and reusable. BaseUrl, Page Object Model and custom commands are important parts of every testing framework. Cypress invested a lot of effort to simplify the usage of their product and improve the overall user experience.

Oh hi there 👋
It’s nice to meet you.

Sign up to receive awesome content in your inbox, every month.

We don’t spam! We keep your data private and share it only with third parties that make this service possible. Read our privacy policy for more info.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.