First Page Object | Bondar Academy
Course: Cypress UI Testing with JavaScript
Module: Page Object Design Pattern
Instructor: Artem Bondar
Lesson Summary
In this lesson, we explored the concept of creating page objects in Cypress for a test application. The main points covered include: Creating Page Objects Each page of the application with an independent URL should have a corresponding JavaScript class as a page object. Exceptions exist for persistent sections of the application, such as the header , footer , or navigation elements, which can also be encapsulated in independent page objects. Implementation Steps Create a new folder named page objects within the Cypress directory. Create a new file named navigation-page.js for the navigation page object. Define a class, e.g., NavigationPage , and export an instance of this class for use in test files. Implement methods within the class for navigation, such as navigateToFormLayoutsPage , navigateToDatePickerPage , etc. Using Page Objects in Tests In the test file, import the page object instance and use its methods for navigation. For example: navigateTo.FormLayoutsPage(); This approach enhances readability and reduces code duplication across tests. Key Takeaways Create a new class for each page or persistent section. Export the class instance for easy access in tests. Utilize methods in the page object for navigation to improve maintainability. In conclusion, the page object design pattern simplifies test structure and enhances code clarity in Cypress.
Video Transcript
All right guys, so let's create our first page object and what we will create it for. Let's jump into the test application and I will show you. So this is our test application and remember, as a high-level concept for the page object, I mentioned that we need to create a new class for every page of the application. When I navigate across different pages like form layouts page or date picker page and so on, every page has a new URL and a rule of thumb for every new page that has independent URL, you should create a new JS class that will be your page object. Within this page object, you will create methods related to interaction on this specific page. But there can be exceptions and one of the exception, I would call different views or screens that located on the screen all the time. For example, the header of the application or the navigation page or the footer. So the section that are on the screen all the time and you may need to interact with those sections at any moment of time during your scenario. In such situation, I also create an independent page object. In this case, we will create this navigation page object. So technically, this is not a page, but this is a section of the page that all the time displayed on our application. So it makes sense to put it into independent page objects. So all methods related to navigation across the pages will be located in a separate object. That way, we can access other pages of our application. So let's create navigation page as the first example. Going back to application. So I created a new spec file, page object.cy.js before each to navigate to the app and new test, navigation test, it's just empty test so far. We're going to keep the page objects. Under the Cypress folder, I create a new folder and I will call it page objects. And all page objects will live right here. Under this folder, I create a new file and I call it navigation-page.js. So keep in mind that I'm using syntax just .js without cy.js. cy.js is a syntax that is used only for the spec files. Files that keep your actual Cypress test. All other files that you will create in the project should be just filename.js. Inside of this file, we need to create a new JavaScript class. So I create class and give it a name. For example, navigation-page and create the class body. Class name always have to start with a capital K, so navigation-page. And after class was created, I want to export the instance of this class right away, so I create the new constant. For example, call it navigate2 equals 2 and create the new instance of this class navigation-page like this. And export this guy right away so I can import this constant, which is instance of our class, in any of my spec files. Now, let's create methods related to navigation to the page objects. For example, we want to navigate to, I don't know, FormLayoutsPage. So let's create a new method, FormLayoutsPage, like this. This is method, and this is the method body. And we take the existing code from application, like these two steps. This is what we need to navigate to this page, Ctrl-C, Ctrl-V, and that's it. That's the implementation for this method. Let's create the second one. Navigate to DatePickerPage. And navigate to this guy, would be the same steps, but it will be DatePicker. DatePicker, and let's create two more examples. So let's grab, for example, ToasterPage. Navigate to ToasterPage like this. And the final one, let's take what it can be. So let's be TooltipPage. TooltipPage. TooltipPage. Like this, Cmd-V, and like this. So, and you got the idea, right? So you create all the methods related to navigation to all the pages that we need during our test scenario. So far, for this example, four is enough. Now, going back to PageObjectsCY.js, how to use it? When I start typing the instance of our class, which is Navigate, and look, VS Code IntelliSense immediately picks up that instance that I exported from the page object. And if I click Enter, it automatically imports this instance over here. And now we can use this inside of the test. So navigate to, I click dot, and look, immediately IntelliSense, again, telling me which available methods do I have within my page object. And I can choose the page of where I want to navigate. For example, navigate to FormLayoutsPage, like this. And then navigate to, let's say, DatePickerPage. And then navigate to, the next one will be, let's say, TooltipPage. And then navigate to, and the last one would be, what is it, ToasterPage. Like this. So simple and easy. So let's try to run it and let's see what's gonna happen. So opening the page objects. Okay, so some webpack compilation error, some extra character. Hold on, let me come back and fix this. So navigation page, okay, this is this guy. Okay, going back, trying to run it. Okay, running the test, and look, all pages were opened successfully. So first we open FormLayoutsPage, then DatePickerPage, then ToasterPage, then TooltipPage, and so on. And now, inside of your test, when you need to run tests across different pages or in different tests, navigate to different pages like we did here in the UI components, like here, or here, and so on. Instead of copy pasting two lines of code every time to open a needed page, you just call the instance of the class and the method that's responsible for it. And also, look, I intentionally gave the name NavigateTo. So when you're reading the test case, it would be like more human readable from the test perspective. NavigateTo FormLayoutsPage, sounds clear and understandable, right? So that's how you create the page objects in Cypress, super, super simple. Because Cypress has this very simplified version of syntax, you don't need to care about, I don't know, instance of the page or something like this. So you create a super simplistic structure of the class file, export it, and then import it to your test, and just use it. You don't need to worry about anything else. And let me show you about one trick that we will break our test intentionally right now, and then we will fix it in the next lesson. So if I, for example, here, we'll add, let's say, CyWeight 500. Just delay between the steps when we select forms and then date picker. And then I go back to the test, and look, the test failed. So why did it happen? Because both of the methods, look, we click on the form, then FormLayouts. And then to select the date picker, it click on the forms one more time. And then I have a Weight 500, just to wait until the menu will be collapsed. So when we click on the forms, again, it collapses the menu. And the date picker menu item is not possible to select. And that's kind of a problem, right? Because if during your test you need to navigate across the different pages, you do not have to think either your menu is expanded or collapsed. You just want to select the page, whatever you need. And that's something that we're gonna implement in this lesson, to handle this logic dynamically. All right, so we stop over here, and let's quickly summarize what we did in this lesson. So when you want to create a new page object, you simply create a new class for every page of your application. Sometimes you may have an exception for the areas that are displayed on the screen all the time. You can create the page objects for that as well. And overall, there are no hard rules in the page object design pattern when you have to create the page. If you have a need of creating a new kind of abstraction layer or new page for some repetitive functionality, go ahead and do it. So you create a new class, then you export the instance of the class within the same class, just for the convenience, so you don't have to do it every time in the test files. And then from the test file level, you just call this instance and then call the methods from this page object, so simple. All right, that's it guys, and I'll see you in the next lesson.