Page Objects Manager | Bondar Academy
Course: Playwright UI Testing with TypeScript
Module: Page Objects
Instructor: Artem Bondar
Lesson Summary
Lesson Overview: In this lesson, we will create a Page Manager , a dedicated class for managing page objects in a testing framework. This approach helps to organize tests better and reduces duplication when dealing with multiple page objects. Key Concepts: Page Object Pattern: A design pattern that encapsulates page-specific actions and elements. Page Manager: A class that manages the instantiation and access of multiple page objects, improving code organization. Steps to Create a Page Manager: Create a new file named pageManager.js in the page object folder. Import the page fixture and define a new class. Initialize fields for each page object (e.g., navigationPage , formLayoutsPage , datePickerPage ). Set up the constructor to assign the page fixture and instantiate each page object using this.page . Create methods to return instances of each page object, such as navigateTo . Refactoring Tests: In the test files, instead of importing each page object, create an instance of the Page Manager : const pm = new PageManager(pageFixture); Replace direct calls to page objects with pm.navigateTo() methods, simplifying the test structure and improving readability. Benefits: Reduced duplication of page object instances. Improved code readability and maintainability. Easy scalability for future page objects. By implementing a Page Manager , tests become cleaner and more efficient, allowing for better management of page objects as the framework grows.
Video Transcript
In this lesson, we will create a page manager. So page manager is a separate class that is responsible for managing page objects. When your framework growing in size and you have more and more page objects created, page object manager helps you to better organize the tests and import your page inside of the test body. So in this lesson, we will create this. Let's get into it. I think you have noticed that we are seeing a building up of a new pattern inside of our test. When we create the page object every time, we need to import this page object into the spec file. And then every time for every single test, we need to create an instance of each of those page objects inside of the test. And we need to repeat this operation for every single test. Now imagine the situation of the real life project when you have 20 pages of your application. In this case, you will have a 20 page objects. And in this case, you will need to import 20 instances of your pages and then write your test. And you will need to repeat this operation again and again for every test. And this sounds like not really optimal approach, right? So we want this to organize a little bit better to make sure that we have less duplication like this when we need to import navigation page here and navigation page here. And in every single test, we need to create this instance of the navigation page and for other pages. So in this lesson, we will create additional helper or manager that will manage all our page objects. And we will interact with this page object manager to get access to all of our page objects that we have created. So I will create a new file under the page object folder and I will call it page manager. And I'm going to import the page fixture, then create a new class. Then as usual, we'll create a field for the page fixture and constructor. Now we will start moving all of our page objects inside of the page manager. So going back to the test and I'm taking all those imports, Control C and importing it here. Then I need to create field for every of our page object. And type for the navigation page will be navigation page and so on for all of our pages. Private read-only form layouts page, type of form layouts page. And the last one, private read-only date picker page of type date picker page. Then we need to call all our pages inside of the constructor, including the page fixture. So first let's assign this page equals to page that we pass into the constructor for the page manager. And then we need to initialize all of our page objects. This navigation page equals to new navigation page. And we need to pass the page fixture inside of the navigation page object. But instead of passing just page, we need to pass that page fixture related to the page object manager, which is this one. So we call here this dot page. This way we will make sure that navigation page, we will use the fixture of the page that we passed from the test into the page manager. And then from the page manager, we are cascading it down to the navigation page right here. So that's why we need to use this dot page. And the same way we need to create the constructors for the rest of the page objects. This forms layout page equals to new form layout page, this page and this date picker page equals to new date picker page, this dot page. All right, we're done with this. And now we need to create a methods that will return for us all the instances of the page objects. And we're gonna call those instances exactly how we made calls right here, like navigate to on forms layout page, on date picker page and so on. Navigate to, I create a new method and inside of the method, I type return this and I want to return navigation page. And similarly doing for the rest of the pages. On form layouts page, return this form layout page. And the last one on date picker page, return this date picker page. All right, that's it. Our page manager is ready. And now let's call this page manager inside of the test. So here, first of all, we need to import this page manager. Page manager. And then instead of calling each page independently from the test, we are creating an instance of the page manager. And I call it, let's say const PM for the convenience new page manager. And of course I pass the instance of the page fixture. And right now we don't need navigate to anymore. And we're replacing here, PM dot navigate to and navigate to right now is a method. And that's it. And the same way we need to do with the second test. I copy the page manager, pasting it here. Now I can remove the instances of all other pages created before in this test and simply replacing it with the page manager instance. PM dot navigate to. Oh, so it's a little bit broken. We need to change it one by one. So let's say, let's say we want to create a refactoring test here. Here, parentheses here, here, here, and here. And what else? And also we can remove these imports as well. So that's it. We made a refactoring. All right, test working successful. So right now our test looks much nicer. We use just the single instance of the page manager that is responsible for all the management of our page objects. And in the future, when our framework growing in the size, we're just adding more instances of the page objects inside of the page manager and still controlling through the single instance of the page manager relation to each of the page object. And also look how nicely we can read our code. You just type PM, navigate to forms layout page. On forms layout page, submit using the grid form with credentials and option. Navigate to date picker. On date picker page, select common date picker, date from today. Also readability of the code improved as well. So we on purpose named the instances of our pages that way. So when we read this line, it's kind of a human language scenario. Same way how you would normally write your test case, right? Navigate to date picker page. On date picker page, select the common date. So very easy to understand, very easy to use, highly reusable code. We removed a lot of duplication and it's very nicely organized. Okay, so let me quickly summarize what we did in this lesson. In order to remove the duplication of the instances of page objects inside of your test, a good way is to create a page manager that will be responsible for building all of your instances of the pages in the single place. So you need to initialize constructor that will create instances of your pages, assign those instances into the fields and then create individual methods that will return this instance to you. Then inside of the test, you just simply create instance of this page manager and interact with your page objects. And by the way, IntelliSense is still working. So if I type pm dot, you can see the instances, for example, navigate to and that dot and all your methods are also available. So this is very useful and very convenient technique to use. All right, that's it guys and see you in the next lesson.