diff --git a/server/src/workflow-management/classes/Generator.ts b/server/src/workflow-management/classes/Generator.ts index 1716531c..7801a20e 100644 --- a/server/src/workflow-management/classes/Generator.ts +++ b/server/src/workflow-management/classes/Generator.ts @@ -559,6 +559,8 @@ export class WorkflowGenerator { if (this.listSelector !== '') { const childSelectors = await getChildSelectors(page, this.listSelector || ''); this.socket.emit('highlighter', { rect, selector: displaySelector, elementInfo, childSelectors }) + console.log(`Child Selectors: ${childSelectors}`) + console.log(`Parent Selector: ${this.listSelector}`) } else { this.socket.emit('highlighter', { rect, selector: displaySelector, elementInfo }); } diff --git a/server/src/workflow-management/selector.ts b/server/src/workflow-management/selector.ts index 18b878ff..193de891 100644 --- a/server/src/workflow-management/selector.ts +++ b/server/src/workflow-management/selector.ts @@ -794,6 +794,7 @@ export const getNonUniqueSelectors = async (page: Page, coordinates: Coordinates export const getChildSelectors = async (page: Page, parentSelector: string): Promise => { try { const childSelectors = await page.evaluate((parentSelector: string) => { + // Function to get a non-unique selector based on tag and class (if present) function getNonUniqueSelector(element: HTMLElement): string { let selector = element.tagName.toLowerCase(); @@ -811,6 +812,7 @@ export const getChildSelectors = async (page: Page, parentSelector: string): Pro return selector; } + // Function to generate selector path from an element to its parent function getSelectorPath(element: HTMLElement | null): string { if (!element || !element.parentElement) return ''; @@ -820,22 +822,33 @@ export const getChildSelectors = async (page: Page, parentSelector: string): Pro return `${parentSelector} > ${elementSelector}`; } - function getAllDescendantSelectors(element: HTMLElement, stopAtParent: HTMLElement | null): string[] { + // Function to recursively get all descendant selectors + function getAllDescendantSelectors(element: HTMLElement): string[] { let selectors: string[] = []; const children = Array.from(element.children) as HTMLElement[]; for (const child of children) { - selectors.push(getSelectorPath(child)); - selectors = selectors.concat(getAllDescendantSelectors(child, stopAtParent)); + const childPath = getSelectorPath(child); + if (childPath) { + selectors.push(childPath); // Add direct child path + selectors = selectors.concat(getAllDescendantSelectors(child)); // Recursively process descendants + } } return selectors; } - const parentElement = document.querySelector(parentSelector) as HTMLElement; - if (!parentElement) return []; + // Find all occurrences of the parent selector in the DOM + const parentElements = Array.from(document.querySelectorAll(parentSelector)) as HTMLElement[]; + const allChildSelectors = new Set(); // Use a set to ensure uniqueness - return getAllDescendantSelectors(parentElement, parentElement); + // Process each parent element and its descendants + parentElements.forEach((parentElement) => { + const descendantSelectors = getAllDescendantSelectors(parentElement); + descendantSelectors.forEach((selector) => allChildSelectors.add(selector)); // Add selectors to the set + }); + + return Array.from(allChildSelectors); // Convert the set back to an array }, parentSelector); return childSelectors || []; @@ -845,6 +858,7 @@ export const getChildSelectors = async (page: Page, parentSelector: string): Pro } }; + /** * Returns the first pair from the given workflow that contains the given selector * inside the where condition, and it is the only selector there. diff --git a/src/components/molecules/RunContent.tsx b/src/components/molecules/RunContent.tsx index ff22a3a8..ff414628 100644 --- a/src/components/molecules/RunContent.tsx +++ b/src/components/molecules/RunContent.tsx @@ -36,14 +36,19 @@ export const RunContent = ({ row, currentLog, interpretationInProgress, logEndRe const firstKey = Object.keys(row.serializableOutput)[0]; const data = row.serializableOutput[firstKey]; if (Array.isArray(data)) { - setTableData(data); - if (data.length > 0) { - setColumns(Object.keys(data[0])); + // Filter out completely empty rows + const filteredData = data.filter(row => + Object.values(row).some(value => value !== undefined && value !== "") + ); + setTableData(filteredData); + if (filteredData.length > 0) { + setColumns(Object.keys(filteredData[0])); } } } }, [row.serializableOutput]); + // Function to convert table data to CSV format const convertToCSV = (data: any[], columns: string[]): string => { const header = columns.join(','); @@ -53,7 +58,6 @@ export const RunContent = ({ row, currentLog, interpretationInProgress, logEndRe return [header, ...rows].join('\n'); }; - // Function to download CSV file when called const downloadCSV = () => { const csvContent = convertToCSV(tableData, columns); const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' }); @@ -140,7 +144,9 @@ export const RunContent = ({ row, currentLog, interpretationInProgress, logEndRe {tableData.map((row, index) => ( {columns.map((column) => ( - {row[column]} + + {row[column] === undefined || row[column] === "" ? "-" : row[column]} + ))} ))}