Skip to content

Commit 248f8d7

Browse files
committed
Add FalkorDB Canvas compatibility: support both data structures and flatten node properties
1 parent dd0c0fd commit 248f8d7

2 files changed

Lines changed: 60 additions & 25 deletions

File tree

e2e/logic/POM/codeGraph.ts

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -624,11 +624,18 @@ export default class CodeGraph extends BasePage {
624624
if (!nodes) throw new Error("No nodes found in graph data!");
625625

626626
const { a, e, d, f } = transformData.transform;
627-
return nodes.map((node: any) => ({
628-
...node,
629-
screenX: transformData.left + node.x * a + e - 35,
630-
screenY: transformData.top + node.y * d + f - 190,
631-
}));
627+
return nodes.map((node: any) => {
628+
// Canvas format has properties nested in 'data' object and 'labels' instead of 'category'
629+
// Flatten the structure for backward compatibility
630+
const flatNode = {
631+
...node,
632+
...(node.data || {}), // Spread data properties to top level
633+
category: node.labels?.[0] || node.category, // Use labels[0] or fallback to category
634+
screenX: transformData.left + node.x * a + e - 35,
635+
screenY: transformData.top + node.y * d + f - 190,
636+
};
637+
return flatNode;
638+
});
632639
}
633640

634641

@@ -679,10 +686,17 @@ export default class CodeGraph extends BasePage {
679686
async getGraphDetails(): Promise<any> {
680687
await this.canvasElementBeforeGraphSelection.waitFor({ state: 'detached' });
681688
await this.waitForCanvasAnimationToEnd();
682-
await this.page.waitForFunction(() => !!window.graph);
689+
690+
// Wait for the graph function to be available and return data
691+
await this.page.waitForFunction(() => {
692+
const data = (window as any).graph?.();
693+
// Check both possible structures: { nodes } or { elements: { nodes } }
694+
return data && ((Array.isArray(data.nodes) && data.nodes.length > 0) ||
695+
(data.elements && Array.isArray(data.elements.nodes) && data.elements.nodes.length > 0));
696+
}, { timeout: 5000 });
683697

684698
const graphData = await this.page.evaluate(() => {
685-
return window.graph;
699+
return (window as any).graph?.();
686700
});
687701

688702
return graphData;

e2e/tests/canvas.spec.ts

Lines changed: 39 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ test.describe("Canvas tests", () => {
6565
await codeGraph.clickOnRemoveNodeViaElementMenu();
6666
const updatedGraph = await codeGraph.getGraphNodes();
6767
const targetNodeForUpdateGraph = findNodeByName(updatedGraph, node.nodeName);
68-
expect(targetNodeForUpdateGraph.visible).toBe(false);
68+
expect(targetNodeForUpdateGraph).toBeUndefined();
6969
});
7070
})
7171

@@ -91,8 +91,9 @@ test.describe("Canvas tests", () => {
9191
await codeGraph.selectGraph(GRAPHRAG_SDK);
9292
await codeGraph.selectCodeGraphCheckbox(checkboxIndex.toString());
9393
const result = await codeGraph.getGraphNodes();
94+
// Canvas filters out hidden nodes, so they should not be found
9495
const findItem = result.find((item: { category: string; }) => item.category === category);
95-
expect(findItem?.visible).toBe(false);
96+
expect(findItem).toBeUndefined();
9697
});
9798
})
9899

@@ -123,8 +124,11 @@ test.describe("Canvas tests", () => {
123124
const codeGraph = await browser.createNewPage(CodeGraph, urls.baseUrl);
124125
await codeGraph.selectGraph(graphName);
125126
const result = await codeGraph.getGraphDetails();
126-
expect(result.elements.nodes.length).toBeGreaterThan(1);
127-
expect(result.elements.links.length).toBeGreaterThan(1);
127+
// Support both data structures: { nodes, links } or { elements: { nodes, links } }
128+
const nodes = result.elements?.nodes || result.nodes;
129+
const links = result.elements?.links || result.links;
130+
expect(nodes.length).toBeGreaterThan(1);
131+
expect(links.length).toBeGreaterThan(1);
128132
});
129133
})
130134

@@ -136,8 +140,10 @@ test.describe("Canvas tests", () => {
136140
const initialGraph = await codeGraph.getGraphNodes();
137141
await codeGraph.changeNodePosition(initialGraph[nodeIndex].screenX, initialGraph[nodeIndex].screenY);
138142
const updateGraph = await codeGraph.getGraphDetails();
139-
expect(updateGraph.elements.nodes[nodeIndex].x).not.toBe(initialGraph[nodeIndex].x);
140-
expect(updateGraph.elements.nodes[nodeIndex].y).not.toBe(initialGraph[nodeIndex].y);
143+
// Support both data structures: { nodes } or { elements: { nodes } }
144+
const nodes = updateGraph.elements?.nodes || updateGraph.nodes;
145+
expect(nodes[nodeIndex].x).not.toBe(initialGraph[nodeIndex].x);
146+
expect(nodes[nodeIndex].y).not.toBe(initialGraph[nodeIndex].y);
141147
});
142148
}
143149

@@ -158,8 +164,14 @@ test.describe("Canvas tests", () => {
158164
const graphData = await codeGraph.getGraphDetails();
159165
const api = new ApiCalls();
160166
const response = await api.getProject(GRAPHRAG_SDK);
161-
const isMatching = graphData.elements.nodes.slice(0, 2).every(
162-
(node: any, index: number) => node.name === response.result.entities.nodes[index].properties.name
167+
168+
// Support both data structures: { nodes } or { elements: { nodes } }
169+
const nodes = graphData.elements?.nodes || graphData.nodes;
170+
const isMatching = nodes.slice(0, 2).every(
171+
(node: any, index: number) => {
172+
const nodeName = node.name || node.data?.name;
173+
return nodeName === response.result.entities.nodes[index].properties.name;
174+
}
163175
);
164176
expect(isMatching).toBe(true)
165177
});
@@ -172,10 +184,14 @@ test.describe("Canvas tests", () => {
172184
await codeGraph.insertInputForShowPath("1", firstNode);
173185
await codeGraph.insertInputForShowPath("2", secondNode);
174186
const result = await codeGraph.getGraphDetails();
175-
const firstNodeRes = findNodeByName(result.elements.nodes, firstNode);
176-
const secondnodeRes = findNodeByName(result.elements.nodes, secondNode);
177-
expect(firstNodeRes.isPath).toBe(true)
178-
expect(secondnodeRes.isPath).toBe(true)
187+
// Support both data structures: { nodes } or { elements: { nodes } }
188+
const nodes = result.elements?.nodes || result.nodes;
189+
const firstNodeRes = findNodeByName(nodes, firstNode);
190+
const secondnodeRes = findNodeByName(nodes, secondNode);
191+
expect(firstNodeRes).toBeDefined();
192+
expect(secondnodeRes).toBeDefined();
193+
expect(firstNodeRes?.isPath).toBe(true)
194+
expect(secondnodeRes?.isPath).toBe(true)
179195
})
180196
})
181197

@@ -187,14 +203,19 @@ test.describe("Canvas tests", () => {
187203
await codeGraph.insertInputForShowPath("1", path.firstNode);
188204
await codeGraph.insertInputForShowPath("2", path.secondNode);
189205
const result = await codeGraph.getGraphDetails();
190-
const firstNodeRes = findNodeByName(result.elements.nodes, path.firstNode);
191-
const secondNodeRes = findNodeByName(result.elements.nodes, path.secondNode);
192-
206+
// Support both data structures: { nodes } or { elements: { nodes } }
207+
const nodes = result.elements?.nodes || result.nodes;
208+
const firstNodeRes = findNodeByName(nodes, path.firstNode);
209+
const secondNodeRes = findNodeByName(nodes, path.secondNode);
210+
211+
expect(firstNodeRes).toBeDefined();
212+
expect(secondNodeRes).toBeDefined();
213+
193214
const api = new ApiCalls();
194-
const response = await api.showPath(GRAPHRAG_SDK ,firstNodeRes.id, secondNodeRes.id);
215+
const response = await api.showPath(GRAPHRAG_SDK ,firstNodeRes!.id, secondNodeRes!.id);
195216
const callsRelationObject = response.result.paths[0].find(item => item.relation === "CALLS")
196-
expect(callsRelationObject?.src_node).toBe(firstNodeRes.id);
197-
expect(callsRelationObject?.dest_node).toBe(secondNodeRes.id);
217+
expect(callsRelationObject?.src_node).toBe(firstNodeRes!.id);
218+
expect(callsRelationObject?.dest_node).toBe(secondNodeRes!.id);
198219
});
199220
})
200221

0 commit comments

Comments
 (0)