4

I have some questions about creating an Object Repository for a selenium project:

1) What are the main reasons that we create an Object Repository, as opposed to hard coding the element IDs in our page classes?

2) What is the best approach to do this? I have seen people use an OR class with public static strings, and others create the OR class with private members with get/setters.

Your input is appreciated!

6 Answers 6

4

The correct approach is to

  • have the locators in each page object class as By variables or

  • use page factory which declares the web elements and their locators together

In my opinion, using object repositories in Selenium projects is a bad practice.

The object repository concept comes from record-and-playback tools such as QTP.

The object repository is a tree-like structure that is created while recording a test.

It has attributes for each element of the page used in the test.

Selenium does not have any record-and-play feature for test automation (Selenium IDE is not an automation tool).

Using object repositories in Selenium projects (as property or csv or xml files) has many disadvantages such as

  1. since each locator is a line in a text file, it is impossible to open the declaration of the locator in the IDE (using F3 or Open Declaration)

  2. page object classes with no locator variables break the class encapsulation principle (methods of a class should execute on variables of a class)

  3. object repositories do not scale well for big pages; since big pages are bad and should be broken down in small pages, should we not have object repositories for each page widget?

  4. object repositories do not work with page factory

Read more about the disadvantages on this medium.com article: https://medium.com/@alexsiminiuc3/dont-use-object-repositories-with-selenium-webdriver-ad14096528e5

1

I guess by object repository you mean external source (a file or DB) of locators for elements in your page objects.

I actually see no reason to follow this approach.

  1. Keeping locators in a separate repository is said to limit maintenance costs, as locators can be updated without a need of recompiling the code. However, both locators and page object codes are usually maintained by the same tester/team, so recompiling is not a big problem.
  2. Rather, I would say this approach increases the costs of maintenance, as locators are decoupled from elements definined in page objects. Hence, if you need to update locators you first need to understand which page object and which elements they refer to. On the other side, if you want to refactor your page object (e.g., rename one of its elements or move an element from one page object to another), you will need to take care for corresponding locators in your object repository, loosing all support your IDE would give you, if both locators and elements where parts of page object classes.

Instead, I would go for a solution with @FindBy annotations, e.g.,

@FindBy(id = "password")
WebElement passwordField;

This gives you a nice balance of separating elements location from operations performed on those elements, like clicking, while still keeping locators close to the elements they identify.

0

I am not sure what is your definition of "Object Repository". I am going to assume it is some kind of central place for locators of page elements (by id, name, link text, css, or even xpath). If i am wrong, we can just kill the answer.

In few places I've seen suggesting one central file for all locators, but it can grow pretty big pretty fast. I am using pageObject design pattern, and locators seems to belong to the page, so I keep them there. I am also using Python so I mostly keep it simple.

2
  • Thanks, I guess one benefit of keeping them in a centralized place is when you use some elements across multiple pages and multiple tests, in this situation, how would you handle? Jun 4, 2014 at 21:34
  • 1
    @user2917239, through PageObject class inheritance. I.e, you could create an abstract class that contains locators/elements used across multiple pages and then multiple PageObject classes that inherit from it.
    – dzieciou
    Jun 5, 2014 at 12:01
0

You can use XML as object repository like

<ObjRep>
<url>http://www.google.com</url>
<search_TxtFld>q</search_TxtFld>
<submt>btnG</submt>
</ObjRep>

And you can use the code for retrieve the objects from xml below is the code:

  public void objRepository(String eleName){
        try{
        File file=new File("F:\\Test.xml");
        DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();
        DocumentBuilder db=dbf.newDocumentBuilder();
        Document doc=db.parse(file);
        doc.getDocumentElement().normalize();
        //System.out.println("The node name is: "+doc.getDocumentElement().getNodeName());  



    NodeList nList=doc.getElementsByTagName("ObjRep");
    //System.out.println("The length is: "+nList.getLength());
    for(int i=0; i<nList.getLength(); i++){
        Node nNode=nList.item(i);
        if(nNode.getNodeType()==Node.ELEMENT_NODE){
          Element ele=(Element) nNode;
          System.out.println(ele.getElementsByTagName(eleName).item(i).getTextContent());
          }
    }

    }catch(Exception e){
        e.printStackTrace();
    }
}

And you can use as

WebDriver d = new FirefoxDriver();
d.get(objRepository(url));
d.findelement(by.name(objRepository(search_TxtFld)).sendkeys("test");
d.findelement(by.name(search_TxtFld(submt)).click();
3
  • Linked sites disappear sometimes without trace. Please try to include the most important parts inline into your answers and link only additional information.
    – Edu
    Nov 17, 2014 at 8:30
  • Sure Edu.Here is the link to the implementation of xml based repository in SO.stackoverflow.com/questions/26758299/… Nov 17, 2014 at 10:00
  • Edited and added one complete code example. Nov 18, 2017 at 19:26
0

The reason we do this is twofold:

  • To DRY up multiple references so that when one locator changes there are not other ones to have to (try) and remember to update

  • To name the parts and make specs readable.

For me its all about the second point.
Here's an example that shows how it makes the spec more readable:

def fill_out_ssn_and_confirm_ssn p
  fill_in p.ssn_first_three, with: '123'
  fill_in p.ssn_middle_two, with: '00'
  fill_in p.ssn_last_four, with: '0000'
end

PageObject file:

...
dob_year: 'BO_DOB3'
ssn_first_three: 'BO_SSN1_mask'
ssn_middle_two: 'BO_SSN2_mask'
ssn_last_four: 'BO_SSN3_mask'
continue: 'button#Continue'
...

It can also be helpful to share objects at a:

  • page level
  • workflow level
  • application level

depending on the application.

As for how see:
Canonical way to define page objects/locators in big enterprise level automation projects?

0

As to how: Define things that belong to the page at the page level, like title and url. Then locators as a sub or extension of the page. A webelement can have multiple locators, getting the locators out of a defined webelement is a pain (reflection only) and usually is needed when you need to wait for a webelement to appear/disappear on a page.

As to why: In selenium it usually is referred to as an Page Factory and not so much an object repository.

If you see an object repo being created anyway it usually is because the people who created it are used to having it like that. As others have suggested prob due to usage of other automation tools.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.