Cracking the Code: My Adventure in JSON Parsing with Selenium WebDriver

Hasan Ozyer
4 min readOct 21, 2023

--

Hi everyone. In today’s article i will try to explain how to read a JSON data with Selenium by executing a test case from TestNG in an automation site called DemoQA.

But because it is so hard to explain a code structure in plain text, I tried my best to make it more understandable by adding comment lines.

1-) Firstly, we need these dependencies imported to your Maven pom.xml file:

<!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java -->
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>4.11.0</version>
</dependency>

<!-- this is for json -->
<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
<version>1.1.1</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.testng/testng -->
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>7.1.0</version>
</dependency>

2-) Then a simple JSON file (Elements.json) that includes the locators and the type’s that we will use in our code:

{
"DemoQA": {
"FullName": {
"type": "xpath",
"locator": "//input[@id='userName']"
},
"Email": {
"type": "id",
"locator": "userEmail"
},
"Current Address": {
"type": "css",
"locator": "#currentAddress"
},
"Permanent Address": {
"type": "classname",
"locator": "btn btn-primary"
}
}
}

3-) Let’s create a Java class and read the JSON:

🔶3.1-) Example of Parsing and Printing JSON Data:

public class JsonReadingClass{
public static void Main(String[] args){

// 1. Defines the file path for the JSON file containing the data.
String jsonFile = "src/test/resources/datafiles/Elements.json";

// 2. Reads the JSON file for the first time and parses it into a JSONObject.
// The contents of the JSON file are parsed and stored in the 'object' variable.
JSONObject object = (JSONObject) JSONValue.parse(new FileReader(jsonFile));

// 3. This statement outputs the entire parsed JSON object to the console.
System.out.println(object);
}

}
/*
The result:
{
"DemoQA": {
"Current Address": {
"type": "css",
"locator": "#currentAddress"
},
"Email": {
"type": "id",
"locator": "userEmail"
},
"Permanent Address": {
"type": "classname",
"locator": "btn btn-primary"
},
"FullName": {
"type": "xpath",
"locator": "//input[@id='userName']"
}
}
}
*/

🔶3.2-) Parsing JSON Element Type and Locator:

public class jsonReadingClass{
public static void Main(String[] args){

String JSONFile = "src/test/resources/datafiles/Elements.json";

// 1. Parses the JSON file as a whole into a JSONObject.
JSONObject object = (JSONObject) JSONValue.parse(new FileReader(JSONFile));

// 2. Extracts the 'FullName' object under the 'DemoQA' section from the parsed JSON data.
JSONObject demoQA = (JSONObject) object.get("DemoQA");
JSONObject fullName = (JSONObject) demoQA.get("FullName");

// 3. Extracts 'type' and 'locator' values from the 'FullName' object.
String type = fullName.get("type").toString();
String locator = fullName.get("locator").toString();

// 4. Prints the extracted 'type' and 'locator' values to the console.
System.out.println("type = " + type);
System.out.println("locator = " + locator);
}

}

/*
The result:
type = xpath
locator = //input[@id='userName']
*/

Okay, we got the basics down, but how on earth would you convert this into something usable? Well, here we will head over to the fourth step. Which is Writing a switch case method:

4-) This method is for Mapping Types to WebDriver Locators:

// This method returns a By object based on the given type and locator.
public static By getBy(String type, String locator) {

switch (type) {
case "xpath" -> {
return By.xpath(locator);
}
case "css" -> {
return By.cssSelector(locator);
}
case "id" -> {
return By.id(locator);
}
case "tagname" -> {
return By.tagName(locator);
}
case "classname" -> {
return By.className(locator);
}
case "linktext" -> {
return By.linkText(locator);
}
case "partiallinktext" -> {
return By.partialLinkText(locator);
}
default -> {
return null;
}
}
}

Now, let’s also mix the Step 3.2 and the Step 4 as a method, because it will be so much easier for us.

5-) JSON Configuration-based Web Element Locating method:

/**
* Retrieves a web element locator using JSON configuration.
*
* @param main The main node within the JSON structure.
* @param sub The sub-node containing 'type' and 'locator' information.
* @return By object representing the located web element.
* @throws FileNotFoundException If the JSON file specified by 'jsonFile' is not found.
*/
public static By getBy(String main, String sub) throws FileNotFoundException {
// 1. Defines the file path for the JSON file containing the data.
String jsonFile = "src/test/resources/datafiles/Elements.json";

// 2. Reads the JSON file and parses its contents into a JSONObject.
JSONObject object = (JSONObject) JSONValue.parse(new FileReader(jsonFile));

// 3. Extracts the JSON objects corresponding to the specified 'main' and 'sub' nodes.
JSONObject mainNode = (JSONObject) object.get(main);
JSONObject subNode = (JSONObject) mainNode.get(sub);

// 4. Extracts 'type' and 'locator' values from the 'sub' node.
String type = subNode.get("type").toString();
String locator = subNode.get("locator").toString();

// 5. Returns a By object based on the extracted 'type' and 'locator'.
switch (type) {
case "xpath" -> {
return By.xpath(locator);
}
case "css" -> {
return By.cssSelector(locator);
}
case "id" -> {
return By.id(locator);
}
case "tagname" -> {
return By.tagName(locator);
}
case "classname" -> {
return By.className(locator);
}
case "linktext" -> {
return By.linkText(locator);
}
case "partiallinktext" -> {
return By.partialLinkText(locator);
}
default -> {
return null;
}
}
}

6-) Here comes the final class to unite the 2 methods above within a test case powered by TestNG!

public class JsonTest {
WebDriver driver;

{
driver = new ChromeDriver();
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
}

@Test
public void test1() throws FileNotFoundException {
driver.get("https://demoqa.com/text-box");
driver.findElement(getBy("DemoQA","FullName")).sendKeys("hasan");
driver.findElement(getBy("DemoQA","Email")).sendKeys("test@test.com");
driver.findElement(getBy("DemoQA","Current Address")).sendKeys("Qatar");
driver.quit();


}

public static By getBy(String main, String sub) throws FileNotFoundException {

String jsonFile = "src/test/resources/datafiles/Elements.json";

JSONObject object = (JSONObject) JSONValue.parse(new FileReader(jsonFile));
JSONObject mainNode = (JSONObject) object.get(main);
JSONObject subNode = (JSONObject) mainNode.get(sub);


String type = subNode.get("type").toString();
String locator = subNode.get("locator").toString();

switch (type) {
case "xpath" -> {
return By.xpath(locator);
}
case "css" -> {
return By.cssSelector(locator);
}
case "id" -> {
return By.id(locator);
}
case "tagname" -> {
return By.tagName(locator);
}
case "classname" -> {
return By.className(locator);
}
case "linktext" -> {
return By.linkText(locator);
}
case "partiallinktext" -> {
return By.partialLinkText(locator);
}
default -> {
return null;
}
}

}

}

In summary, this code demonstrates a basic Selenium WebDriver test case that interacts with the elements on a page using locators fetched from a JSON file.

🎗️Connect with me on LinkedIn: Hasan Özyer | LinkedIn

🎗️Check out my GitHub: hasanozye (Hasan) (github.com)

🎗️For inquiries, please feel free to reach me at: hasanozyer06@gmail.com

--

--

Hasan Ozyer

Junior Test Automation Engineer. Documenting my IT journey for my future self. Sharing my opinions, learnings, and adventures in the tech world.