The Data/fetchCellDataFromTable extension retrieves the visible text from a specific table cell on the current page. It uses an XPath expression to locate table rows, then selects the requested row and column using 1-based numbering.
This is useful when a journey needs to validate a value from a dynamic HTML table, compare a displayed table cell against expected test data, or store a specific cell value for use in later steps.
Parameters:
-
Xpathrequired, a string XPath expression that returns the target table data rows, for example//table[@id="example"]//tbody//tr; -
RowNumberrequired, an integer or numeric value representing the 1-based row number to read from the XPath result. The first matched data row is1; -
ColumnNumberrequired, an integer or numeric value representing the 1-based column number to read from the selected row. The firsttdcell is1.
Note: The XPath should point to the table row elements, not to an individual cell. The extension reads only td cells inside the selected row, so header cells such as th are not counted by this implementation.
How to apply this to your journey
Use the extension in a journey by calling Data/fetchCellDataFromTable with the execute command. Pass each value to the matching extension input using as inputName.
Note: This extension runs synchronously and returns the trimmed text from the selected cell. If the row or column is not found, it logs the issue and returns null.
execute "Data/fetchCellDataFromTable" using "//table[@id=\"example\"]//tbody//tr" as Xpath, "2" as RowNumber and "3" as ColumnNumber returning $responseexecute "Data/fetchCellDataFromTable" using "//table[contains(@class, \"orders-table\")]//tbody//tr" as Xpath, "1" as RowNumber and "2" as ColumnNumber returning $cellValueYou can also pass XPath, row number, and column number from journey variables when the table location or cell position is determined earlier in the test.
execute "Data/fetchCellDataFromTable" using "$tableRowsXpath" as Xpath, "$rowNumber" as RowNumber and "$columnNumber" as ColumnNumber returning $responsestore value "//table[@id=\"example\"]//tbody//tr" in $tableRowsXpath
store value "2" in $rowNumber
store value "3" in $columnNumber
execute "Data/fetchCellDataFromTable" using "$tableRowsXpath" as Xpath, "$rowNumber" as RowNumber and "$columnNumber" as ColumnNumber returning $responseExample output when the selected cell contains the text Completed:
CompletedThis extension does not require any external resource.
The extension should be configured as:
- Run asynchronously: No
- Scope: Global
Limitation: This extension depends on the table rows that are available in the page DOM at the exact moment the Virtuoso step runs. It does not wait for delayed rendering, pagination, filtering, virtualized rows, animations, or SPA updates, so add suitable journey waits before calling it when the table loads dynamically. The XPath must return row elements, and the implementation reads only td cells, which means header cells, nested table structures, hidden responsive columns, or tables rendered without standard td elements may return unexpected values or null. It uses browser DOM APIs including document.evaluate, XPath snapshots, querySelectorAll, and textContent; when used in cross-browser, mobile, or remote-grid executions, validate the journey in each browser/device configuration because DOM structure, responsive layout, iframe context, and timing can differ from the default browser. If the target table is inside an iframe, the journey must execute the extension in the correct frame context, and browser same-origin restrictions can prevent access to cross-origin or sandboxed frame content.
Add the extension to your Virtuoso instance
Select the domain that matches your Virtuoso account.
View source
Last updated: 04/06/2026
Resources:
This extension does not require any external resource.
function getData(xpath, rowNumber, columnNumber) {
// Use XPath to find the rows
const rows = document.evaluate(xpath, document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
if (rows.snapshotLength < rowNumber) {
console.error(`Row number ${rowNumber} does not exist.`);
return null;
}
const row = rows.snapshotItem(rowNumber - 1);
if (!row) {
console.error(`Row number ${rowNumber} does not exist.`);
return null;
}
// Get all columns within the row
const columns = row.querySelectorAll('td');
if (columns.length < columnNumber) {
console.error(`Column index ${columnNumber} does not exist in row number ${rowNumber}.`);
return null;
}
// Select the text content of the specified column
const cell = columns[columnNumber - 1];
return cell.textContent.trim();
}
// Example usage
const xpath = Xpath;
const rowNumber = RowNumber; // row excluding the header row
const columnNumber = ColumnNumber; // column
const data = getData(xpath, rowNumber, columnNumber);
console.log(data); // Output the data
return data;
Comments
0 comments
Please sign in to leave a comment.