Simplifying Automated Tests for Dynamic Pages with Relicx

Gurashish Brar
Transforming testing with Generative AI
3 min readJun 21, 2024

Writing test automation code, especially for Dynamic pages can be tricky. Traditional selectors often fall short when the target elements change with the content or require dynamic identification. Let’s explore this with an example on Southwest’s flight listing page

Scenario:

We aim to select a Business Select option for a flight departing between 7 am and 9 am. In test automation, such specific actions might be necessary to validate the presence of a flight within a particular time frame.

Traditional Approach:

Using conventional automation tools, this task involves complex JavaScript code to navigate a custom table structure made of nested divs. The process involves:

  1. Understanding the table structure by exploring the DOM,
  2. Identifying the row with a departure time within the desired range.
  3. Selecting the Business Select column for that row.

Table structure in the DOM

Here is a sample JS code that can accomplish this.

function getMinutesOfDay(timeString) {
// Match the time and the AM/PM part
const timePattern = /(\d{1,2}):(\d{2})(AM|PM)/;
const match = timeString.match(timePattern);

if (match) {
let hours = parseInt(match[1], 10);
const minutes = parseInt(match[2], 10);
const period = match[3];

// Convert hours to 24-hour format
if (period === 'PM' && hours !== 12) {
hours += 12;
} else if (period === 'AM' && hours === 12) {
hours = 0;
}

// Calculate total minutes of the day
const totalMinutes = hours * 60 + minutes;

return totalMinutes;
}

return null; // Return null if the input format is incorrect
}

function findFlightRowDepartingBetween(fromTime, toTime) {
const fromMinuteOfDay = getMinutesOfDay(fromTime);
const toMinuteOfDay = getMinutesOfDay(toTime);
if (!fromMinuteOfDay || !toMinuteOfDay) {
return null;
}
const table = document.querySelector("#air-search-results-matrix-0");
for(const row of table.children) {
const departureCell = row.querySelector(".time--value");
const departureText = departureCell.innerText.split("\n")[1];
const departureMinuteOfDay = getMinutesOfDay(departureText);
if (!departureMinuteOfDay) {
continue;
}
if (fromMinuteOfDay <= departureMinuteOfDay && departureMinuteOfDay < toMinuteOfDay) {
return row;
}
}
return null;
}

const flightRow = findFlightRowDepartingBetween("7:00AM", "9:00AM");
const businessCellButton = flightRow.querySelector("#air-booking-fares-0-4 > div:nth-child(1) > button")
businessCellButton.click();

This is nontrivial code and it contains assumptions that can break easily:

  • Table layout: The layout and organization of rows/cells with nested divs can change
  • Time Field Structure: The unstructured nature of the time field and potential layout/format changes necessitate frequent updates to the getMinutesOfDay function.
  • Brittle Selectors: The selectors are prone to breaking if the layout, IDs, or class values change.

Simplified Solution with Relicx:

With Relicx, developers can bypass complex logic and focus on the desired test outcome. By using natural language commands, Relicx Agent automatically identifies the correct elements to interact with, simplifying the entire process.

Natural Language Command:

Select business select option that departs between 7 am to 9 am

Relicx’s agent handles the intricacies, ensuring that the specified action is performed accurately without the need for detailed code.

A short video demonstrating Relicx Agent in action

Conclusion:

Relicx revolutionizes test automation by allowing developers to define “what-to-test” rather than “how-to-test.” This shift reduces complexity, enhances efficiency, and minimizes maintenance efforts, making automated testing more robust and adaptable to changes.

--

--