Instantiate multiple page objects in 1 test file


#1

Is it possible to instantiate multiple page objects in one test file?


#2

Hello @micheleaz!

Yes, you can instantiate multiple page object files in your test file. Ranorex Webtestit best practice is to follow the Page Object pattern. You can find out more about this topic here. Basically, the idea is to have all your elements and corresponding actions stored in the page object files and available to use in single or multiple Test files, which will result in simple, but robust and maintainable tests. For example, if you take a look at our java-demoshop test, you will notice all of the page object files instantiated in the test file.

To instantiate a Page Object in your test simply use the context menu within the test file or the (CTRL + I CTRL + P )keyboard shortcut.


#3

Thank you! I appreciate the assistance!


#4

To ponder a bit more on the topic, one design principle of Page Objects is that their methods should return:

  • A base type such as String, Integer, Boolean etc for Getters
  • Reference to self (this) for normal actions
  • New instance of follow-up page-object for actions crossing the border from PoA to PoB

The idea with the later to is that you can express your tests as a chain. If you take a look at the above sample from the demoshop you’ll see that addItem1ToCart() returns it self, as does addItem2ToCart(). Thats why you can call the functions in a chain. But clickOnCart on line 22 performs actually a page navigation, thus it returns the next follow up PageObject CartPo. Now our sample for explaining purposes (the comments) assigned it to a variable cart but in reality you could go straight away on and just chain the next method proceedToCheckout right away.


#5

Hi. I have an additional question. So here is the flow of my test. I currently have 2 Page Objects. The first page object is the origin page object-- it is called HomePO. I initialize that and give the URL. Here is the code for that–

    HomePo home = new HomePo(driver);
    home.open("http://xxx.xx.xx.xxx/sep19/");
    driver.manage().window().maximize();

Then I want to click on Actions in the Nav Bar. Here is the command for that–

home.clickActionsNav();

Then I want to verify within another page object that the page that I am landing on is what I expect. In the second page object, which is called MyActionsPO-- I have this Boolean (Does exist defined)
public Boolean isMy_ActionsPresent() {
Boolean My_ActionsIsPresent = driver.findElements(this.My_Actions).size() > 0;

          return My_ActionsIsPresent;

So do I need to instantiate the second page object? You don’t have any boolean exists in your code above so I am wondering exactly how to call this-- here is what I have but I don’t think it is right
Boolean myActionBoolean = MyActionsPo.isMy_ActionsPresent();
Assert.assertTrue(myActionBoolean);


#6

Hello @micheleaz

As @vsoftic explained above you would have to have a return type of new instance of follow-up page-object for actions crossing the border from PoA to PoB.

In your case, the HomePO has this .clickActionsNav() method. After performing the click action, you are using the second (MyAccounsPO) Page Object where your boolean is located as you said.

Now following the Page Object pattern you would have the clickActionsNav() (Page Object A - HomePO) method return a new instance of the (Page Object B - MyAccountsPO).

  public MyAccountsPO clickActionsNav() {
         this.wait.until(ExpectedConditions.visibilityOfElementLocated(this.actions)).click();
     
         
         return new MyAccountsPO(driver);
     }

Afterward, you instantiate the second (MyAccountsPO) in the Test File by performing the action from the first PageObject (HomePO) so that you have a nice “chain” like order in your test. Finally, you can assert your boolean value.

 @Test
    public void SampleTestCase() {
       WebDriver driver = getDriver();

       // Instantiate the Page Object A - HomePO)
       HomePO home = new HomePO(driver);
       home.open("https://www.yourPage.com");
       
       // Instantiate the Page Object B - MyAccountsPO)
       MyAccountsPO accounts = home.clickActionsNav();

       // Get the Boolean from the Page Object B
       boolean yourBoolean = accounts.My_ActionsIsPresent();

       // Perform the assert
       Assert.assertTrue(yourBoolean);
       
    }

#7

What @smatijas said is the way to go. Additionally I wanted to remark that this line driver.manage().window().maximize(); is also not well placed there.
In general, following the PageObject pattern helps to keep your tests isolated from any AutomationFramework. That is your tests shouldn’t include any driver.xx specific code.

In your current scenario I would see two ways to handle that.
A. put that maximize code inside the open function of your HomePo
B. create an explicit method called e.g maximizeBrowserWindow() where you do the job.

With A, you hide that specific feature from the consumer, whereas with B you make it explicitly available. This really depends on preferences and to how you want your resulting domain specific language (DSL) to be. While A is helpful to define a general workflow and make you not think about maximizing anymore, B is more flexible for scenarios where you sometimes need a non-maximized window.


#8

Hi @vsoftic! I like your idea of creating an explicit method and calling maximize. Where would you put the method? I was thinking about SuiteConfiguration.java?
Thanks!


#9

Hello @micheleaz
As said, it is totally up to you where you will place the maximize method. SuiteConfiguration.java is also fine, or for example some helper file that you can create, as long as you can instantiate it and call your maximizeBrowserWindow() method when you need it.
Main thing the driver.manage().window().maximize() method is not placed in the actual test file, and like Simon Stewart, the lead committer of the Selenium Project said, "If you have WebDriver APIs in your test methods, You’re Doing It Wrong.”


#10

Hi @micheleaz,

as described in my scenario I would personally go with putting the maximzeBrowserWindow part into the open method of the entry PageObject. Keep in mind that if you have multiple entry points each of those POs open method should contain that maximize logic.

The reason for that is a personal opinion because I think it makes the PO self-contained and expressive. But going with SuiteConfig is fine as well if you always only want to test on maximized.