1

Imagine there is a page say http://google.com/AddUser and here you enter details for a record and click save. Once you do this the page redirects to

http://google.com/userList

where you can see list of users including the new record you just entered.

If we are going by page object model, the method to enter details and save record should exist on AddUser.java and the method to validate if the record was actually saved and displayed should be on UserList.java

If we consider addUser and userList are the corresponding objects for both classes it will be something like below :

addUser.enterDetailsSaveRecord();

userList.validateSavedRecord();

So in my Test case i would need to call 2 separate methods, one for the action and other to validate.

Both AddUser.java and UserList.java have BasePage.java as the superclass. Is there a way to club them both into a single method or is there something I'm going about in a wrong way and is there a better approach?

Thank you

undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
Shrik97
  • 59
  • 1
  • 1
  • 8
  • what is the problem with the current approach. what you described is your implementation, which I find nothing wrong. – Gaurang Shah Sep 12 '17 at 08:21

3 Answers3

1

I don't see anything wrong with your approach either, although, my approach is usually to logically separate functional interaction with the application from testing functions. So, I would still have

addUser.enterDetailsSaveRecord();

but for userList I would use

UserItem foundUser = userList.findUser(targetUser);

where UserItem is a row in the table of users. My test would then verify that foundUser was correct.

Although this ends up with a few more lines of code, it results in the object model cleanly and simply modeling the object under test, and the testing code being found in the test itself.

Breaks Software
  • 1,721
  • 1
  • 10
  • 15
  • This is the way I create my page objects also. Best practice is to keep the validation code out of the page objects. The way to get around that is to have the page objects return the data needed and have the script itself do the validation in an `Assert`. – JeffC Sep 12 '17 at 14:24
1

Using PageFactory you are having 2 PageObjects as AddUser.java and UserList.java. So assuming you are passing the appropriate arguments while invoking the methods, the following works for you:

addUser.enterDetailsSaveRecord();
userList.validateSavedRecord();

But a word from Best Practices, Assertions should be done in a seperate utility/package/class which is in similar line with @JeffC comment:

Best practice is to keep the validation code out of the page objects

Hence, you should be creating a seperate common utility/package/class which will handle all the Assertions. You can call the class containing the Assertions from your PageObject class as well.

So your entire Test Environment will contain 3 Packages. One package containing the main()/@Test class, one package containing the PageObjects e.g. AddUser.java and one Utility package with the class for containing the Assertions e.g validateSavedRecord().

undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
-1

Your approach is correct. These methods should belong to different pages. Please update method as:

public UserList enterDetailsSaveRecord() {
// your code to save the details
return new UserList();
}

thus you can use it as:

addUser.enterDetailsSaveRecord().validateSavedRecord()
  • You can't validate the saved record until you are on the UserList page. Your code listed above doesn't demonstrate that clearly. – JeffC Sep 12 '17 at 14:25
  • As soon as you enterDetails and click save, website will automatically redirect you to new page. Above code just showing the instead of creating a new object in test script, we can create new object in method itself (Factory method) and can used as chaining in the same line – Pankaj Sharma Sep 12 '17 at 16:31
  • Yeah but that turns into a mess because if you go crazy with this, you can have `page1.dosomeThingOnPage2().dosomeThingOnPage3().dosomeThingOnPage4().dosomeThingOnPage5();` and you end up with a one liner that is navigating through the entire site. It makes it very hard to follow what is going on. – JeffC Sep 12 '17 at 20:41
  • Yes, you're right, you will end up with one liner and you will come to know that it is necessary and important step in terms of memory management. – Pankaj Sharma Sep 13 '17 at 04:43
  • This definitely makes it less readable, why do you think it has advantages in memory management? While chaining, you still create each page object as you would without chaining. – JeffC Sep 13 '17 at 13:07