Using JSON Files for Managing Test Data in Playwright

3 min readAug 7, 2024

Recently, I joined a new product team where we are developing UI validation tests with Playwright and TypeScript. Previously, I had mostly worked with Playwright using Cucumber.js as a test runner. However, this time we decided to use the Playwright test runner. Over the past few months, I’ve learned a lot and will be sharing many insights here.

During one such scenario, I was required to automate a huge set of dropdowns with similar components. Consider a page that has let’s say ten grids, where each grid has three different dropdowns. These dropdowns are common across individual grids.

At first, I wrote the test something like this:

const testData = [
{
criteria: 'City',
comparator: 'equal to',
value: 'Pune'
},
{
criteria: 'State',
comparator: 'equal to',
value: 'Maharashtra'
},
{
criteria: 'Pin',
comparator: 'greater than',
value: '4211'
},
{
criteria: 'Country',
comparator: 'contains',
value: 'Ind'
},
{
criteria: 'Continent',
comparator: 'equal to',
value: 'Asia'
},
..........

]

for(data of testData) {
await this.locator['Add New Button'].click();
await this.selectCriteria(data.criteria);
await this.selectComparator(data.comparator);
await this.selectValue(data.value);
}

This code looks well optimized as we are not repeating the steps to first click on the ‘Add New’ button and then select values from each dropdown set. And then repeating the same stuff for every set. Instead, an array object is created to define the data, and then a for loop is utilized to iterate through each object and perform the selection of dropdown values.

Optimizing Test Data Management

However, this encapsulation of test data and the logic looks a bit lengthy. Then, I thought of moving the test data to some other location, somewhere like test-data. Initially, I wanted to keep most of the relevant test data in a .ts file and export them. However, I learned later that it is a good practice to store array objects in a .json file instead.

So, we can store the test data array object in a .json file something like this:

[
{
"criteria": "City",
"comparator": "equal to",
"value": "Pune"
},
{
"criteria": "State",
"comparator": "equal to",
"value": "Maharashtra"
},
{
"criteria": "Pin",
"comparator": "greater than",
"value": "4211"
},
{
"criteria": "Country",
"comparator": "contains",
"value": "Ind"
},
{
"criteria": "Continent",
"comparator": "equal to",
"value": "Asia"
}
]

Now, before importing this JSON, open your tsconfig.json file and ensure that the resolveJsonModule and esModuleInterop options are enabled. It should look something like this:

{
"compilerOptions": {
"resolveJsonModule": true,
"esModuleInterop": true,
// other options...
}
}

Now, this is how the method in a page object class will look like:

// page-object class 

async selectDropdownValues(data: {
criteria: string;
comparator: string;
value: string;
}[])
for(data of testData) {
await this.locator['Add New Button'].click();
await this.selectCriteria(data.criteria);
await this.selectComparator(data.comparator);
await this.selectValue(data.value);
}

This method can be invoked in a spect.tsfile by passing an array object as an argument. We need to import a JSON file which can be used as an argument to selectDropdownValues() .

// spec.ts file

import data '../test-data/dropdown.json';

test('some test', async() => {
await pageObjectInstance.selectDropdownValues(data);
})

Conclusion

This way, we can define our test data in a more structured manner in a JSON file and optimize the function body smartly. This approach enhances code maintainability and readability, especially when dealing with large sets of test data.

Shiv Jirwankar
SDET

LinkedIn

--

--

Shiv Jirwankar
Shiv Jirwankar

Written by Shiv Jirwankar

Software Development Engineer in Test | An ambivert, optimistic, and karma believer | https://www.linkedin.com/in/shiv-jirwankar-45246577

Responses (1)