diff --git a/openmetadata-ui/src/main/resources/ui/cypress/constants/constants.js b/openmetadata-ui/src/main/resources/ui/cypress/constants/constants.js index ab836f6b602..d6aa894314b 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/constants/constants.js +++ b/openmetadata-ui/src/main/resources/ui/cypress/constants/constants.js @@ -210,6 +210,13 @@ export const NEW_GLOSSARY = { reviewer: 'Aaron Johnson', tag: 'PII.None', }; +export const NEW_GLOSSARY_1 = { + name: 'Product Glossary', + description: 'This is the Product glossary', + reviewer: 'Brandy Miller', + tag: 'PII.None', +}; + export const NEW_GLOSSARY_TERMS = { term_1: { name: 'Purchase', @@ -223,6 +230,19 @@ export const NEW_GLOSSARY_TERMS = { }, }; +export const NEW_GLOSSARY_1_TERMS = { + term_1: { + name: 'Features', + description: 'This is the Features', + synonyms: 'data,collect,time', + }, + term_2: { + name: 'Uses', + description: 'This is the Uses', + synonyms: 'home,business,adventure', + }, +}; + export const service = { name: 'Glue', description: 'This is a Glue service', diff --git a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/Glossary.spec.js b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/Glossary.spec.js index 69ca72f3e71..5d3cfd18733 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/Glossary.spec.js +++ b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/Glossary.spec.js @@ -21,6 +21,8 @@ import { import { DELETE_TERM, NEW_GLOSSARY, + NEW_GLOSSARY_1, + NEW_GLOSSARY_1_TERMS, NEW_GLOSSARY_TERMS, SEARCH_ENTITY_TABLE, } from '../../constants/constants'; @@ -37,12 +39,12 @@ const visitGlossaryTermPage = (termName) => { .click(); }; -const createGlossaryTerm = (term) => { +const createGlossaryTerm = (term, glossary, isMutually = false) => { cy.get('[data-testid="breadcrumb-link"]') .scrollIntoView() .should('exist') .and('be.visible') - .contains(NEW_GLOSSARY.name) + .contains(glossary.name) .should('exist'); cy.get('[data-testid="add-new-tag-button"]').should('be.visible').click(); @@ -59,12 +61,13 @@ const createGlossaryTerm = (term) => { .scrollIntoView() .should('be.visible') .type(term.synonyms); - cy.get('[data-testid="mutually-exclusive-button"]') - .scrollIntoView() - .should('exist') - .should('be.visible') - .click(); - + if (isMutually) { + cy.get('[data-testid="mutually-exclusive-button"]') + .scrollIntoView() + .should('exist') + .should('be.visible') + .click(); + } cy.get('[data-testid="references"] > .ant-space-item > .button-comp') .scrollIntoView() .should('be.visible') @@ -92,7 +95,7 @@ const createGlossaryTerm = (term) => { .should('be.visible'); }; -const deleteGlossary = ({ name }) => { +const deleteGlossaryTerm = ({ name }) => { visitGlossaryTermPage(name); cy.wait(500); cy.get('[data-testid="inactive-link"]').contains(name).should('be.visible'); @@ -245,6 +248,34 @@ describe('Glossary page should work properly', () => { cy.contains(NEW_GLOSSARY.name); }); }); + + // Adding another Glossary with mutually exclusive flag off + cy.get('[data-testid="add-glossary"]').should('be.visible').click(); + cy.get('[data-testid="name"]') + .scrollIntoView() + .should('be.visible') + .type(NEW_GLOSSARY_1.name); + + cy.get(descriptionBox) + .scrollIntoView() + .should('be.visible') + .type(NEW_GLOSSARY_1.description); + + cy.get('[data-testid="save-glossary"]') + .scrollIntoView() + .should('be.visible') + .click(); + + cy.wait('@createGlossary').then(() => { + cy.url().should('include', '/glossary/'); + cy.get('[data-testid="breadcrumb-link"]') + .scrollIntoView() + .should('exist') + .and('be.visible') + .within(() => { + cy.contains(NEW_GLOSSARY_1.name); + }); + }); }); it('Verify added glossary details', () => { @@ -268,12 +299,41 @@ describe('Glossary page should work properly', () => { .then((text) => { expect(text).to.contain(NEW_GLOSSARY.reviewer); }); + + // Verify Product glossary details + cy.get('.ant-menu-item') + .contains(NEW_GLOSSARY_1.name) + .should('be.visible') + .click(); + + cy.get('[data-testid="glossary-left-panel"]') + .contains(NEW_GLOSSARY_1.name) + .should('be.visible'); + cy.get('[data-testid="header"]') + .invoke('text') + .then((text) => { + expect(text).to.contain(NEW_GLOSSARY_1.name); + }); + cy.get('[data-testid="viewer-container"]') + .invoke('text') + .then((text) => { + expect(text).to.contain(NEW_GLOSSARY_1.description); + }); }); it('Create glossary term should work properly', () => { const terms = Object.values(NEW_GLOSSARY_TERMS); + terms.forEach((term) => createGlossaryTerm(term, NEW_GLOSSARY, true)); - terms.forEach(createGlossaryTerm); + // Glossary term for Product glossary + + cy.get('.ant-menu-item') + .contains(NEW_GLOSSARY_1.name) + .should('be.visible') + .click(); + + const ProductTerms = Object.values(NEW_GLOSSARY_1_TERMS); + ProductTerms.forEach((term) => createGlossaryTerm(term, NEW_GLOSSARY_1)); }); it('Updating data of glossary should work properly', () => { @@ -484,9 +544,21 @@ describe('Glossary page should work properly', () => { it('Assets Tab should work properly', () => { const glossary = NEW_GLOSSARY.name; - const term = NEW_GLOSSARY_TERMS.term_1.name; + const term1 = NEW_GLOSSARY_TERMS.term_1.name; + const term2 = NEW_GLOSSARY_TERMS.term_2.name; + + const glossary1 = NEW_GLOSSARY_1.name; + const term3 = NEW_GLOSSARY_1_TERMS.term_1.name; + const term4 = NEW_GLOSSARY_1_TERMS.term_2.name; + const entity = SEARCH_ENTITY_TABLE.table_3; - goToAssetsTab(term); + + cy.get('.ant-menu-item') + .contains(NEW_GLOSSARY_1.name) + .should('be.visible') + .click(); + + goToAssetsTab(term3); cy.contains('No assets available.').should('be.visible'); cy.get('[data-testid="no-data-image"]').should('be.visible'); visitEntityDetailsPage(entity.term, entity.serviceName, entity.entity); @@ -499,22 +571,62 @@ describe('Glossary page should work properly', () => { cy.get('[data-testid="tag-selector"]') .should('be.visible') .click() - .type(`${glossary}.${term}`); - cy.get(`[title*="${term}"]`).should('be.visible').click(); + .type(`${glossary}.${term1}`); + cy.get(`[title*="${term1}"]`).should('be.visible').click(); cy.get( '[data-testid="tags-wrapper"] [data-testid="tag-container"]' - ).contains(term); + ).contains(term1); - interceptURL('GET', '/api/v1/feed/count*', 'saveTag'); + cy.get('[data-testid="tag-selector"]') + .should('be.visible') + .click() + .type(`${glossary}.${term2}`); + cy.get(`[title*="${term2}"]`).should('be.visible').click(); + cy.get( + '[data-testid="tags-wrapper"] [data-testid="tag-container"]' + ).contains(term2); + + interceptURL('GET', '/api/v1/feed/count*', 'countTag'); interceptURL('GET', '/api/v1/tags', 'tags'); + interceptURL('PATCH', '/api/v1/tables/*', 'saveTag'); cy.get('[data-testid="saveAssociatedTag"]').should('be.visible').click(); + verifyResponseStatusCode('@saveTag', 400); + toastNotification( + `Tag labels ${glossary}.${term2} and ${glossary}.${term1} are mutually exclusive and can't be assigned together` + ); + // Add non mutually exclusive tags + cy.get('[data-testid="tag-container"] [data-testid="tags"]') + .eq(0) + .should('be.visible') + .click(); + + cy.get('[data-testid="tag-selector"]') + .should('be.visible') + .click() + .type(`${glossary1}.${term3}`); + cy.get(`[title*="${term3}"]`).should('be.visible').click(); + cy.get( + '[data-testid="tags-wrapper"] [data-testid="tag-container"]' + ).contains(term3); + + cy.get('[data-testid="tag-selector"]') + .should('be.visible') + .click() + .type(`${glossary1}.${term4}`); + cy.get(`[title*="${term4}"]`).should('be.visible').click(); + cy.get( + '[data-testid="tags-wrapper"] [data-testid="tag-container"]' + ).contains(term4); + + cy.get('[data-testid="saveAssociatedTag"]').should('be.visible').click(); verifyResponseStatusCode('@saveTag', 200); + verifyResponseStatusCode('@countTag', 200); cy.get('[data-testid="entity-tags"]') .scrollIntoView() .should('be.visible') - .contains(term); + .contains(term3); // Add tag to schema table cy.get( @@ -527,18 +639,18 @@ describe('Glossary page should work properly', () => { cy.get('[data-testid="tag-selector"]') .should('be.visible') .click() - .type(`${glossary}.${term}`); - cy.get(`[title*="${term}"]`).should('be.visible').click(); + .type(`${glossary1}.${term3}`); + cy.get(`[title*="${term3}"]`).should('be.visible').click(); cy.get( '[data-row-key="comments"] [data-testid="tags-wrapper"] [data-testid="tag-container"]' - ).contains(term); + ).contains(term3); cy.get('[data-testid="saveAssociatedTag"]').should('be.visible').click(); - verifyResponseStatusCode('@saveTag', 200); - cy.get(`[data-testid="tag-${glossary}.${term}"]`) + verifyResponseStatusCode('@countTag', 200); + cy.get(`[data-testid="tag-${glossary1}.${term3}"]`) .scrollIntoView() .should('be.visible') - .contains(term); + .contains(term3); cy.get('[data-testid="governance"]') .should('exist') @@ -549,16 +661,26 @@ describe('Glossary page should work properly', () => { .should('be.visible') .click(); - goToAssetsTab(term); + cy.get('.ant-menu-item') + .contains(NEW_GLOSSARY_1.name) + .should('be.visible') + .click(); + goToAssetsTab(term3); + cy.get(`[data-testid="${entity.serviceName}-${entity.term}"]`) .contains(entity.term) .should('be.visible'); }); it('Remove Glossary term from entity should work properly', () => { - const term = NEW_GLOSSARY_TERMS.term_1.name; + const term = NEW_GLOSSARY_1_TERMS.term_1.name; const entity = SEARCH_ENTITY_TABLE.table_3; + cy.get('.ant-menu-item') + .contains(NEW_GLOSSARY_1.name) + .should('be.visible') + .click(); + interceptURL('GET', '/api/v1/search/query*', 'assetTab'); // go assets tab goToAssetsTab(term); @@ -595,9 +717,6 @@ describe('Glossary page should work properly', () => { .should('not.contain', term) .and('not.contain', 'Personal'); // Remove the added column tag from entity - - cy.get('[data-testid="remove"]').eq(0).should('be.visible').click(); - cy.wait(200); interceptURL('PATCH', '/api/v1/tables/*', 'removeSchemaTags'); cy.get('[data-testid="remove"]').eq(0).should('be.visible').click(); verifyResponseStatusCode('@removeSchemaTags', 200); @@ -616,6 +735,12 @@ describe('Glossary page should work properly', () => { .click(); cy.wait(500); + + cy.get('.ant-menu-item') + .contains(NEW_GLOSSARY_1.name) + .should('be.visible') + .click(); + goToAssetsTab(term); cy.contains('No assets available.').should('be.visible'); cy.get('[data-testid="no-data-image"]').should('be.visible'); @@ -624,41 +749,51 @@ describe('Glossary page should work properly', () => { it('Delete glossary term should work properly', () => { const terms = Object.values(NEW_GLOSSARY_TERMS); - terms.forEach(deleteGlossary); + terms.forEach(deleteGlossaryTerm); + // Glossary term for Product glossary + + cy.get('.ant-menu-item') + .contains(NEW_GLOSSARY_1.name) + .should('be.visible') + .click(); + + Object.values(NEW_GLOSSARY_1_TERMS).forEach(deleteGlossaryTerm); }); it('Delete glossary should work properly', () => { - verifyResponseStatusCode('@fetchGlossaries', 200); - cy.get('[data-testid="header"]') - .should('be.visible') - .contains(NEW_GLOSSARY.name) - .should('exist'); - cy.get('[data-testid="manage-button"]').should('be.visible').click(); - cy.get('[data-testid="delete-button"]') - .scrollIntoView() - .should('be.visible') - .click(); + [NEW_GLOSSARY.name, NEW_GLOSSARY_1.name].forEach((glossary) => { + verifyResponseStatusCode('@fetchGlossaries', 200); + cy.get('[data-testid="header"]') + .should('be.visible') + .contains(glossary) + .should('exist'); + cy.get('[data-testid="manage-button"]').should('be.visible').click(); + cy.get('[data-testid="delete-button"]') + .scrollIntoView() + .should('be.visible') + .click(); - cy.get('[data-testid="delete-confirmation-modal"]') - .should('exist') - .then(() => { - cy.get('[role="dialog"]').should('be.visible'); - cy.get('[data-testid="modal-header"]').should('be.visible'); - }); - cy.get('[data-testid="modal-header"]') - .should('be.visible') - .should('contain', `Delete ${NEW_GLOSSARY.name}`); - cy.get('[data-testid="confirmation-text-input"]') - .should('be.visible') - .type(DELETE_TERM); - interceptURL('DELETE', '/api/v1/glossaries/*', 'getGlossary'); - cy.get('[data-testid="confirm-button"]') - .should('be.visible') - .should('not.disabled') - .click(); - verifyResponseStatusCode('@getGlossary', 200); + cy.get('[data-testid="delete-confirmation-modal"]') + .should('exist') + .then(() => { + cy.get('[role="dialog"]').should('be.visible'); + cy.get('[data-testid="modal-header"]').should('be.visible'); + }); + cy.get('[data-testid="modal-header"]') + .should('be.visible') + .should('contain', `Delete ${glossary}`); + cy.get('[data-testid="confirmation-text-input"]') + .should('be.visible') + .type(DELETE_TERM); + interceptURL('DELETE', '/api/v1/glossaries/*', 'getGlossary'); + cy.get('[data-testid="confirm-button"]') + .should('be.visible') + .should('not.disabled') + .click(); + verifyResponseStatusCode('@getGlossary', 200); - toastNotification('Glossary deleted successfully!'); + toastNotification('Glossary deleted successfully!'); + }); cy.contains('Add New Glossary').should('be.visible'); }); });