An Object Repository is a central location that is used to keep the locators in the form of objects. The Major advantages of maintaining an object repository are readability, maintainability and reusability. In this article, we will discuss several approaches to maintaining the object repository in Selenium.
Types of Object Repository in Selenium
Page object Model or POM is a trendy approach in the Selenium framework where an Object repository is maintained in the form of page classes but in this article, we will see different approaches.
1)Object Repository using a properties file.
2)Object Repository using YAML file.
3)Object Repository using XML file.
1)Selenium Object repository using the Properties file
Data is stored in properties files in the form of key-value pairs.
1)To start with create a properties file by right click -> new -> file
2)Give it a name for example locators.properties
3)Open properties files and store locators in the form of keys and values.
Home="//span[normalize-space()='Home']"
EmailTextBox = home-email
SignUpButton = home-submit
4)Read data from the properties file. Create a class, name it as ReadPropertyFile and add the below code.
public final class ReadingPropertiesFile {
private static Properties properties = new Properties();
public static String getValue(String key) throws Exception
{
String value="";
InputStream input=new FileInputStream("locator.properties file path");
properties.load(input);
value=properties.getProperty(key);
if(Objects.isNull(value))
{
throw new Exception("property name" +key+"is not found.Please check config.properties");
}
return value;
}}
5) Start using the properties file in the Test class.
driver.findElement(By.xpath(ReadingPropertiesFile.getValue("Home"))).click();
driver.findElement(By.id(ReadingPropertiesFile.getValue("EmailTextBox"))).sendKeys("[email protected]");
driver.findElement(By.id(ReadingPropertiesFile.getValue("SignUpButton"))).click();
Advantage: This approach is useful for small projects where all the locators can be stored in properties files and reusable across the framework. Another benefit is that locators are externalized from the framework, so a less experienced person can access and make changes in the locator.properties file in case of failure due to locator changes. He/she need not look into the entire framework to update the locators.
Disadvantage: This approach is not suitable for large projects because it’s not feasible to write thousands of locators in the properties file and access it from there for readability purposes.
2)Selenium Object repository using the XML File
XML (Extensible Markup Language) is one of the commonly used approaches to storing and sending data.
- Click on New -> Other ->Select XML file ->Click next
- Enter the name as locator.xml and click save.
- Insert the XML declaration and add the root element.
<?xml version="1.0" encoding="UTF-8"?>
<root></root>
4. Under the root node provide the locators.
<locator>
<gmail>//a[text()='Gmail']</gmail>
<image>//a[text()='Images']</image>
<search>//input[@name='q']</search>
</locator>
5. Create a class ReadObjectRepository and add the below code.
public class ReadObjectRepository {
public static String readXmlData(String data) throws ParserConfigurationException, SAXException, IOException {
File file = new File("/Users/varsha/Downloads/Hello-World-JAVA-master/DemoSampleApp_selenium/NewFile.xml");
DocumentBuilderFactory Df = DocumentBuilderFactory.newInstance();
DocumentBuilder Db = Df.newDocumentBuilder();
Document document = Db.parse(file);
NodeList list = document.getElementsByTagName("locator");
Node node1 = list.item(0);
Element ele = (Element) node1;
return ele.getElementsByTagName(data).item(0).getTextContent();
}
6)Navigate to the test class and modify the code to read the locators from the XML file.
WebDriverManager.chromedriver().setup();
ChromeOptions options = new ChromeOptions();
options.addArguments("--remote-allow-origins=*");
WebDriver driver = new ChromeDriver(options);
driver.get("https://www.google.com");
driver.findElement(By.xpath(readXmlData("gmail"))).click();
driver.navigate().back();
driver.findElement(By.xpath(readXmlData("image"))).click();
driver.navigate().back();
driver.findElement(By.xpath(readXmlData("search"))).sendKeys("Selenium", Keys.ENTER);
driver.quit();
As per the requirement, the XML file can be enhanced to accommodate more tags like Type and value to improve readability.
<?xml version="1.0" encoding="UTF-8"?>
<Modules>
<Element>
<NameOfElement>AccountsSearchField</NameOfElement>
<ElementProperty>
<Type>xpath</Type>
<Value>//input[@name='textFilter']</Value>
</ElementProperty>
</Element>
<Element>
<NameOfElement>MyHealthSearchResult</NameOfElement>
<ElementProperty>
<Type>xpath</Type>
<Value>//*[@id="main"]/div[3]/div[2]/a</Value>
</ElementProperty>
</Element>
</Modules>
In the above code snippet we can see that we have modified the XML file in a more modular and readable format. I have added different tags like “NameOfElement”, and then further added element properties like “Type” and “Value”. This way our XML is more refined.
To read Nested XML nodes add the below code in your class file.
File inputFile = new File("/Users/varsha/Downloads/Hello-World-JAVA-master/DemoSampleApp_selenium/NewFile.xml");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(inputFile);
doc.getDocumentElement().normalize();
System.out.println("Root element :" + doc.getDocumentElement().getNodeName());
NodeList nList = doc.getElementsByTagName("Element");
for (int temp = 0; temp < nList.getLength(); temp++) {
Node nNode = nList.item(temp);
System.out.println("\nCurrent Element :" + nNode.getNodeName());
if (nNode.getNodeType() == Node.ELEMENT_NODE) {
Element eElement = (Element) nNode;
System.out.println("NameOfElement : "
+ eElement
.getElementsByTagName("NameOfElement")
.item(0)
.getTextContent());
System.out.println("Type : "
+ eElement
.getElementsByTagName("Type")
.item(0)
.getTextContent());
System.out.println("Value: "
+ eElement
.getElementsByTagName("Value")
.item(0)
.getTextContent());
}
}
After execution, you will get all the Node information that can be utilized in the test scripts.
Apart from these 2 approaches discussed above, there are several ways by which an object repository can be maintained. Just like the Properties file we can manage locators in the YAML file. Similar to the XML approach we can configure JSON files to read locators or can use excels, and CSV to externalize the objects.