Skip to content

Commit 45a0cb1

Browse files
karanh37OpenMetadata Release Bot
authored andcommitted
add playwright for circular reference (#24625)
(cherry picked from commit eefc9aa)
1 parent df4f227 commit 45a0cb1

File tree

1 file changed

+149
-0
lines changed

1 file changed

+149
-0
lines changed

openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/GlossaryImportExport.spec.ts

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,4 +250,153 @@ test.describe('Glossary Bulk Import Export', () => {
250250
}
251251
});
252252
});
253+
254+
test('Check for Circular Reference in Glossary Import', async ({
255+
page,
256+
browser,
257+
}) => {
258+
const circularRefGlossary = new Glossary('Test CSV');
259+
260+
try {
261+
await test.step(
262+
'Create glossary for circular reference test',
263+
async () => {
264+
const { apiContext, afterAction } = await createNewPage(browser);
265+
266+
await circularRefGlossary.create(apiContext);
267+
await afterAction();
268+
}
269+
);
270+
271+
await test.step('Import initial glossary terms', async () => {
272+
await sidebarClick(page, SidebarItem.GLOSSARY);
273+
await selectActiveGlossary(page, circularRefGlossary.data.displayName);
274+
275+
await page.click('[data-testid="manage-button"]');
276+
await page.click('[data-testid="import-button-description"]');
277+
278+
const initialCsvContent = `parent,name*,displayName,description,synonyms,relatedTerms,references,tags,reviewers,owner,glossaryStatus,color,iconURL,extension
279+
,name1,name1,<p>name1</p>,,,,,,user:admin,Approved,,,
280+
,parent,parent,<p>parent</p>,,,,,,user:admin,Approved,,,
281+
${circularRefGlossary.data.name}.parent,child,child,<p>child</p>,,,,,,user:admin,Approved,,,`;
282+
283+
const initialCsvBlob = new Blob([initialCsvContent], {
284+
type: 'text/csv',
285+
});
286+
const initialCsvFile = new File([initialCsvBlob], 'initial-terms.csv', {
287+
type: 'text/csv',
288+
});
289+
290+
const fileInput = page.getByTestId('upload-file-widget');
291+
292+
await fileInput?.setInputFiles([
293+
{
294+
name: initialCsvFile.name,
295+
mimeType: initialCsvFile.type,
296+
buffer: Buffer.from(await initialCsvFile.arrayBuffer()),
297+
},
298+
]);
299+
300+
await page.waitForTimeout(500);
301+
302+
await expect(page.locator('.rdg-header-row')).toBeVisible();
303+
304+
await page.getByRole('button', { name: 'Next' }).click();
305+
306+
const loader = page.locator(
307+
'.inovua-react-toolkit-load-mask__background-layer'
308+
);
309+
310+
await loader.waitFor({ state: 'hidden' });
311+
312+
await validateImportStatus(page, {
313+
passed: '4',
314+
processed: '4',
315+
failed: '0',
316+
});
317+
318+
await page.getByRole('button', { name: 'Update' }).click();
319+
await page
320+
.locator('.inovua-react-toolkit-load-mask__background-layer')
321+
.waitFor({ state: 'detached' });
322+
323+
await toastNotification(
324+
page,
325+
`Glossaryterm ${circularRefGlossary.responseData.fullyQualifiedName} details updated successfully`
326+
);
327+
});
328+
329+
await test.step(
330+
'Import CSV with circular reference and verify error',
331+
async () => {
332+
await sidebarClick(page, SidebarItem.GLOSSARY);
333+
await selectActiveGlossary(
334+
page,
335+
circularRefGlossary.data.displayName
336+
);
337+
338+
await page.click('[data-testid="manage-button"]');
339+
await page.click('[data-testid="import-button-description"]');
340+
341+
const circularCsvContent = `parent,name*,displayName,description,synonyms,relatedTerms,references,tags,reviewers,owner,glossaryStatus,color,iconURL,extension
342+
${circularRefGlossary.data.name}.name1,name1,name1,<p>name1</p>,,,,,,user:admin,Approved,,,
343+
,parent,parent,<p>parent</p>,,,,,,user:admin,Approved,,,
344+
${circularRefGlossary.data.name}.parent,child,child,<p>child</p>,,,,,,user:admin,Approved,,,`;
345+
346+
const circularCsvBlob = new Blob([circularCsvContent], {
347+
type: 'text/csv',
348+
});
349+
const circularCsvFile = new File(
350+
[circularCsvBlob],
351+
'circular-reference.csv',
352+
{
353+
type: 'text/csv',
354+
}
355+
);
356+
357+
const fileInput = page.getByTestId('upload-file-widget');
358+
359+
await fileInput?.setInputFiles([
360+
{
361+
name: circularCsvFile.name,
362+
mimeType: circularCsvFile.type,
363+
buffer: Buffer.from(await circularCsvFile.arrayBuffer()),
364+
},
365+
]);
366+
367+
await page.waitForTimeout(500);
368+
369+
await expect(page.locator('.rdg-header-row')).toBeVisible();
370+
371+
await page.getByRole('button', { name: 'Next' }).click();
372+
373+
const loader = page.locator(
374+
'.inovua-react-toolkit-load-mask__background-layer'
375+
);
376+
377+
await loader.waitFor({ state: 'hidden' });
378+
379+
await validateImportStatus(page, {
380+
passed: '3',
381+
processed: '4',
382+
failed: '1',
383+
});
384+
385+
const rows = await page.$$('.rdg-row');
386+
const firstRow = rows[0];
387+
const detailsCell = await firstRow.$('.rdg-cell-details');
388+
const errorText = await detailsCell?.textContent();
389+
390+
expect(errorText).toContain(
391+
"Invalid hierarchy: Term 'Test CSV.name1' cannot be its own parent"
392+
);
393+
}
394+
);
395+
} finally {
396+
const { apiContext, afterAction } = await createNewPage(browser);
397+
398+
await circularRefGlossary.delete(apiContext);
399+
await afterAction();
400+
}
401+
});
253402
});

0 commit comments

Comments
 (0)