If you have ever wished to have more structured, reusable, and readable automated tests, you should have started with the Page Object Pattern.
Page Object Pattern
Page Object Pattern is basically removing all the page information from your actual test and grouping them together considering their location on your web page. For example, you can take all the selectors that you have on the homepage of your web and put them in one class, give them more meaningful names and then call them in any of your tests ...
Imagine your homepage went through a design and development modification that impacted your selectors to change, you would need to go through all of your tests and change the same selector in all the places. However, with the page object pattern, you change the selector only in one place - in the class that you have created for the homepage selectors. There, you saved yourself a lot of time and made sure that there won't be some forgotten, unchanged, and obsolete selectors in one of your tests.
Adding More of Reusability
Nevertheless, you can make your tests even more structured, reusable, understandable, and easier to maintain, by adding custom commands and reusable functions to them. The same way I made a class for homepage selectors I also made a class for all the functions from the homepage, that are used all over the different tests. For example, if I had 5 different tests/test cases where a user fills out the same form, I wouldn't be needed to copy/paste Cypress code to every each of the tests but I'd reuse the already written functions.
Example how my Cypress test would look like with the page object pattern and reusable functions:
describe("Fill out user satisfaction form", function () {
it("Check if the user can fill out the form", function () {
cy.visitFormsPage();
cy.userAcceptsTerms();
cy.userFillsOutsTheForm();
cy.formFilledOutCorrectlyAssert();
});
});
All together now
Combining page object pattern and reusable functions gave me a whole new perspective of the tests. Not only are they easier to use and maintain, but they also look very neat and easier to understand for my other colleagues, even non-technical members of the team. In the beginning, you need to spend a bit more time on the setup but later on, you will see that the effort is paid off.
Feel free to share with me some of your "reusability" secrets.
Top comments (6)
In the majority of cases, we prefer to build our automation framework using the Page Object Model (POM) design pattern.
Now, imagine having a 🔨 tool that automatically records and generates
POM(page classes) for us. How much easier would our work become?
⚙ Applitools TestGenAI for Cypress provides us this capability.
applitools.com/blog/transform-user...
🔍 Applitools TestGenAI for Cypress empowers users to quickly create robust, auto healing automated tests that can validate even the most complex scenarios within seconds.
How did you solve verification / assertion?
You can still do assertions if you write your elements in the POM class to return the cy objects.
Example:
usernameField(){
return cy.get(#username)
}
And then in your test file you can just chain cy commands of it.
loginPage.usernameField().should('be.visible')
Hi Nenad! Thanks for the question. If needed, I assert directly in the function, so it is completely standalone.
I prefer to do the assertions in the test file. Becuase then the POM element can be used for various assertions without having to duplicate them.
Also the test should be where all the checks take place. If the check is in an external function then we lose test clarity.
Page object pattern is so decade ago.
Check out dev.to/muratkeremozcan/functional-...