Skip to content

Commit 10838ad

Browse files
committed
add tests (#886, #899)
1 parent 55228c3 commit 10838ad

File tree

5 files changed

+425
-60
lines changed

5 files changed

+425
-60
lines changed

app/schema/SchemaCreateElement.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -581,7 +581,7 @@ export default function SchemaCreateElement({ onCreate, onExpand, selectedNodes,
581581
</Table>
582582
{
583583
!type &&
584-
<div className="w-full flex flex-col gap-4">
584+
<div className="w-full flex flex-col gap-4" id="relationship-controls">
585585
<div className="w-full flex justify-between p-8 items-center">
586586
<div style={{ backgroundColor: selectedNodes[0]?.color }} className="flex h-16 w-16 rounded-full border-2 border-foreground justify-center items-center">
587587
<p>{selectedNodes[0]?.category}</p>

e2e/logic/POM/graphPage.ts

Lines changed: 43 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ export default class GraphPage extends BasePage {
4242
return this.page.locator("//button[contains(text(), 'Export Data')]");
4343
}
4444

45+
private get duplicateBtn(): Locator {
46+
return this.page.locator("//button[contains(text(), 'Duplicate')]");
47+
}
48+
4549
private get exportDataConfirmBtn(): Locator {
4650
return this.page.getByRole("button", { name: "Download" });
4751
}
@@ -258,6 +262,18 @@ export default class GraphPage extends BasePage {
258262
return this.page.locator("//div[contains(@class, 'tree')]//div[contains(@class, 'contents')]");
259263
}
260264

265+
private get viewSchemaBtn(): Locator {
266+
return this.page.locator("//button[contains(., 'View Schema')]");
267+
}
268+
269+
private get duplicateGraphInput(): Locator {
270+
return this.page.locator("//div[@id='dialog']//input");
271+
}
272+
273+
private get duplicateConfirmInDialog(): Locator {
274+
return this.page.locator("//div[@id='dialog']//button[contains(text(), 'Duplicate')]");
275+
}
276+
261277
async insertGraphInSearchInput(graph: string, label: string): Promise<void> {
262278
await interactWhenVisible(this.graphSelectSearchInput(label), el => el.fill(graph), "graph search input");
263279
}
@@ -316,6 +332,10 @@ export default class GraphPage extends BasePage {
316332
await interactWhenVisible(this.exportDataBtn, el => el.click(), "export data button");
317333
}
318334

335+
async clickDuplicateButton(): Promise<void> {
336+
await interactWhenVisible(this.duplicateBtn, el => el.click(), "duplicate data button");
337+
}
338+
319339
async clickExportDataConfirmButton(): Promise<void> {
320340
await interactWhenVisible(this.exportDataConfirmBtn, el => el.click(), "confirm export data button");
321341
}
@@ -409,9 +429,7 @@ export default class GraphPage extends BasePage {
409429
}
410430

411431
async hoverOnHeaderDataPanelList(): Promise<void> {
412-
await interactWhenVisible(this.headerDataPanelList, async (el) => {
413-
await el.hover();
414-
}, `Header data panel list`);
432+
await interactWhenVisible(this.headerDataPanelList, async (el) => { await el.hover(); }, `Header data panel list`);
415433
}
416434

417435
async getLastLabelInCanvas(): Promise<string | null> {
@@ -533,6 +551,22 @@ export default class GraphPage extends BasePage {
533551
return await interactWhenVisible(this.edgesGraphStats, el => el.textContent(), "edges graph stats button");
534552
}
535553

554+
async clickViewSchema(): Promise<void> {
555+
await interactWhenVisible(this.viewSchemaBtn, el => el.click(), "view schema button");
556+
}
557+
558+
async getNodeCanvasToolTip(): Promise<string | null> {
559+
return await interactWhenVisible(this.nodeCanvasToolTip, el => el.textContent(), "node canvas tool tip");
560+
}
561+
562+
async fillDuplicateGraphInput(graph: string): Promise<void> {
563+
await interactWhenVisible(this.duplicateGraphInput, el => el.fill(graph), "duplicate graph input");
564+
}
565+
566+
async clickDuplicateConfirmInDialog(): Promise<void> {
567+
return await interactWhenVisible(this.duplicateConfirmInDialog, el => el.click(), "duplicate graph confirm");
568+
}
569+
536570
async getQuerySearchListText(): Promise<string[]> {
537571
await waitForElementToBeVisible(this.querySearchList);
538572
const elements = this.querySearchListItems;
@@ -672,12 +706,6 @@ export default class GraphPage extends BasePage {
672706
return isVisible;
673707
}
674708

675-
async getNodeCanvasToolTip(): Promise<string | null> {
676-
await this.page.waitForTimeout(1000);
677-
const toolTipText = await this.nodeCanvasToolTip.textContent();
678-
return toolTipText;
679-
}
680-
681709
// eslint-disable-next-line class-methods-use-this
682710
async getCanvasTransform(canvasElement: Locator): Promise<any> {
683711
let transformData = null;
@@ -887,4 +915,10 @@ export default class GraphPage extends BasePage {
887915
await this.clickDeleteRelationBtnInDataPanel();
888916
await this.clickConfirmDeleteNodeInDataPanel();
889917
}
918+
919+
async duplicateGraph(newGraph: string): Promise<void> {
920+
await this.clickDuplicateButton();
921+
await this.fillDuplicateGraphInput(newGraph);
922+
await this.clickDuplicateConfirmInDialog();
923+
}
890924
}

e2e/logic/POM/schemaPage.ts

Lines changed: 116 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,38 @@ export default class SchemaPage extends GraphPage {
126126
return this.page.locator(`//ul[@id='TypeList']//div[@role="option"]`);
127127
}
128128

129+
private get LabelDataPanel(): Locator {
130+
return this.page.locator("//div[contains(@class, 'DataPanel')]//li//button");
131+
}
132+
133+
private get clearRelationBtnInDataPanel(): Locator {
134+
return this.page.locator(`//button[contains(text(), 'Clear')]`);
135+
}
136+
137+
private get swapRelationBtnInDataPanel(): Locator {
138+
return this.page.locator(`//button[contains(text(), 'Swap')]`);
139+
}
140+
141+
private get relationshipNodes(): (keyIndex: string) => Locator {
142+
return (keyIndex: string) => this.page.locator(`//div[@id='relationship-controls']/div[1]/div[${keyIndex}]`);
143+
}
144+
145+
private get lastSchemaAttributeValue(): Locator {
146+
return this.page.locator('//div[contains(@id, "tableContent")]//tr[last()]//td[1]');
147+
}
148+
149+
private get actionButtonInLastAttributeRow(): (action: string) => Locator {
150+
return (action: string) => this.page.locator(`//div[contains(@id, "tableContent")]//tr[last()]/td[last()]//button[contains(text(), '${action}')]`);
151+
}
152+
153+
private get saveAttributeBtnInSchemaDataPanel(): Locator {
154+
return this.page.locator('//div[contains(@id, "tableContent")]//button[contains(text(), "Save")]');
155+
}
156+
157+
private get attributesStatsInSchemaDataPanel(): Locator {
158+
return this.page.locator('(//div[contains(@id, "headerDataPanel")]//p)[last()]');
159+
}
160+
129161
async clickAddNewSchemaBtn(): Promise<void> {
130162
await interactWhenVisible(this.addSchemaBtnInNavBar, el => el.click(), "add new schema button");
131163
}
@@ -174,7 +206,7 @@ export default class SchemaPage extends GraphPage {
174206
await interactWhenVisible(this.activeDescInputInDataPanel, el => el.fill(desc), "desc input in data panel");
175207
}
176208

177-
async getDescInDataPanelAttr(descIndex: string): Promise<string | null> {
209+
async getFirstDescInDataPanelAttr(descIndex: string): Promise<string | null> {
178210
return await interactWhenVisible(this.descInDataPanel(descIndex), el => el.textContent(), "desc input in data panel");
179211
}
180212

@@ -226,6 +258,7 @@ export default class SchemaPage extends GraphPage {
226258
}
227259

228260
async getAttributeRowsCount(): Promise<number> {
261+
await this.page.waitForTimeout(500);
229262
return await this.attributeRows.count();
230263
}
231264

@@ -252,11 +285,51 @@ export default class SchemaPage extends GraphPage {
252285
async clickSearchedType(): Promise<void> {
253286
await interactWhenVisible(this.selectSearchType, el => el.click(), "type search input");
254287
}
288+
289+
async hoverOnLabelDataPanel(): Promise<void> {
290+
await interactWhenVisible(this.LabelDataPanel, async (el) => { await el.hover(); }, `Header data panel list`);
291+
}
292+
293+
async clickOnDeleteLabel(): Promise<void> {
294+
await interactWhenVisible(this.LabelDataPanel.first(), async (el) => { await el.click(); }, `Header data panel list`);
295+
}
296+
297+
async clickClearRelationBtnInDataPanel(): Promise<void> {
298+
await interactWhenVisible(this.clearRelationBtnInDataPanel, el => el.click(), "clear relation button in data panel");
299+
}
300+
301+
async clickSwapRelationBtnInDataPanel(): Promise<void> {
302+
await interactWhenVisible(this.swapRelationBtnInDataPanel, el => el.click(), "swap relation button in data panel");
303+
}
304+
305+
async findRelationshipNodes(key: string): Promise<string | null> {
306+
return await interactWhenVisible(this.relationshipNodes(key), el => el.textContent(), "swap relation button in data panel");
307+
}
308+
309+
async hoverLastSchemaAttributeValue(): Promise<void> {
310+
await interactWhenVisible(this.lastSchemaAttributeValue, async (el) => { await el.hover(); }, `last schema attribute value`);
311+
}
312+
313+
async clickActionButtonInLastAttributeRow(action: string): Promise<void> {
314+
await interactWhenVisible(this.actionButtonInLastAttributeRow(action), async (el) => { await el.click(); }, `action buttonn in last attribute row`);
315+
}
316+
317+
async clickSaveAttributeBtnInSchemaDataPanel(): Promise<void> {
318+
await interactWhenVisible(this.saveAttributeBtnInSchemaDataPanel, el => el.click(), "save attribute button in data panel");
319+
}
320+
321+
async getAttributesStatsInSchemaDataPanel(): Promise<string | null> {
322+
return await interactWhenVisible(this.attributesStatsInSchemaDataPanel, el => el.textContent(), "attr stats in data panel");
323+
}
255324

256325
async isCategoriesPanelBtnHidden(): Promise<boolean> {
257326
return await this.categoriesPanelBtn.isHidden();
258327
}
259328

329+
async getCategoriesPanelCount(): Promise<number> {
330+
return await this.categoriesPanelBtn.count();
331+
}
332+
260333
async addSchema(schemaName: string): Promise<void> {
261334
await this.clickAddNewSchemaBtn();
262335
await this.fillSchemaNameInput(schemaName);
@@ -272,28 +345,53 @@ export default class SchemaPage extends GraphPage {
272345
await this.clickCreateNewNodeBtnInDataPanel();
273346
}
274347

348+
async modifyNodeLabel(x: number, y: number, title: string): Promise<void> {
349+
await this.nodeClick(x, y);
350+
await this.hoverOnLabelDataPanel();
351+
await this.clickAddBtnInHeaderDataPanel();
352+
await this.insertDataPanelHeader(title);
353+
await this.clickSaveBtnInHeaderDataPanel();
354+
await this.clickOnDeleteLabel();
355+
}
356+
275357
async deleteNode(x: number, y: number): Promise<void>{
276358
await this.nodeClick(x, y);
277359
await this.clickDeleteNodeInDataPanel();
278360
await this.clickConfirmDeleteNodeInDataPanel();
279361
}
280362

281-
async addLabel(title: string): Promise<void>{
363+
async addRelationLabel(title: string): Promise<void>{
282364
await this.clickAddRelation();
283365
await this.clickAddBtnInHeaderDataPanel();
284366
await this.insertDataPanelHeader(title);
285367
await this.clickSaveBtnInHeaderDataPanel();
286368
}
287369

370+
async clearNodeRelation(): Promise<void>{
371+
await this.clickAddRelation();
372+
await this.selectFirstTwoNodesForRelation();
373+
await this.clickClearRelationBtnInDataPanel();
374+
}
375+
376+
async swapNodesInRelation(): Promise<void> {
377+
await this.clickAddRelation();
378+
await this.selectFirstTwoNodesForRelation();
379+
await this.clickSwapRelationBtnInDataPanel();
380+
}
381+
288382
async prepareRelation(title: string, key: string, type: string, desc: string, unique: boolean, required: boolean): Promise<void> {
289-
await this.addLabel(title);
383+
await this.addRelationLabel(title);
290384
await this.addAttribute(key, type, desc, unique, required);
291385
}
292-
293-
async clickRelationBetweenNodes(): Promise<void> {
386+
387+
async selectFirstTwoNodesForRelation(): Promise<void> {
294388
const schema = await this.getNodeScreenPositions('schema');
295389
await this.nodeClick(schema[0].screenX, schema[0].screenY);
296390
await this.nodeClick(schema[1].screenX, schema[1].screenY);
391+
}
392+
393+
async clickRelationBetweenNodes(): Promise<void> {
394+
await this.selectFirstTwoNodesForRelation();
297395
await this.clickCreateNewEdgeBtnInDataPanel();
298396
}
299397

@@ -321,5 +419,18 @@ export default class SchemaPage extends GraphPage {
321419
}
322420
await this.clickAddActiveBtnInDataPanel();
323421
}
422+
423+
async deleteAttriubute(): Promise<void> {
424+
await this.hoverLastSchemaAttributeValue();
425+
await this.clickActionButtonInLastAttributeRow('Delete');
426+
await this.clickConfirmDeleteNodeInDataPanel();
427+
}
428+
429+
async modifyAttriubuteDesc(desc: string): Promise<void> {
430+
await this.hoverLastSchemaAttributeValue();
431+
await this.clickActionButtonInLastAttributeRow('Edit');
432+
await this.insertActiveDescInputInDataPanelAttr(desc);
433+
await this.clickSaveAttributeBtnInSchemaDataPanel();
434+
}
324435

325436
}

e2e/tests/graph.spec.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -629,4 +629,30 @@ test.describe('Graph Tests', () => {
629629
expect(parseInt(await graph.getAttributesStatsInDataPanel() ?? "", 10)).toBe(1);
630630
await apiCall.removeGraph(graphName);
631631
});
632+
633+
test(`@admin Validate adding a schema for graph creation and ensure it's visible in the schema view`, async () => {
634+
const graphName = getRandomString('graph');
635+
apiCall.addGraph(graphName)
636+
await apiCall.runSchemaQuery(graphName, 'CREATE (a:person1 {id: "Integer!*-1"}), (b:person2 {id: "Integer!*-2"}), (a)-[:knows]->(b) RETURN a, b');
637+
const graph = await browser.createNewPage(GraphPage, urls.graphUrl);
638+
await browser.setPageToFullScreen();
639+
await graph.selectExistingGraph(graphName);
640+
await graph.clickViewSchema();
641+
expect(await graph.getRelationshipTypesPanelBtn()).toBe("knows");
642+
await apiCall.removeSchema(graphName);
643+
});
644+
645+
test(`@admin validate that duplicating a graph creates a new one with a unique name successfully`, async () => {
646+
const graphName = getRandomString('graph');
647+
await apiCall.runQuery(graphName, 'CREATE (a:person1 {id: "Integer!*-1"}), (b:person2 {id: "Integer!*-2"}), (a)-[:knows]->(b) RETURN a, b');
648+
const graph = await browser.createNewPage(GraphPage, urls.graphUrl);
649+
await browser.setPageToFullScreen();
650+
await graph.selectExistingGraph(graphName);
651+
const newGraphName = getRandomString('graph')
652+
await graph.duplicateGraph(newGraphName);
653+
expect((await graph.getNodesGraphStats() ?? "", 0)).toBe(2);
654+
expect((await graph.getEdgesGraphStats() ?? "", 0)).toBe(1);
655+
await apiCall.removeGraph(graphName);
656+
await apiCall.removeGraph(newGraphName);
657+
});
632658
})

0 commit comments

Comments
 (0)