diff --git a/openmetadata-ui/src/main/resources/ui/cypress/common/CustomizeLandingPageUtils.js b/openmetadata-ui/src/main/resources/ui/cypress/common/CustomizeLandingPageUtils.js index 3f231647da77..5cce96e36662 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/common/CustomizeLandingPageUtils.js +++ b/openmetadata-ui/src/main/resources/ui/cypress/common/CustomizeLandingPageUtils.js @@ -47,7 +47,8 @@ export const navigateToCustomizeLandingPage = ({ }) => { interceptURL('GET', '/api/v1/teams/name/*', 'settingsPage'); - cy.get('[data-testid="app-bar-item-settings"]').click(); + cy.sidebarClick('app-bar-item-settings'); + verifyResponseStatusCode('@settingsPage', 200); cy.get('[data-testid="settings-left-panel"]').should('be.visible'); diff --git a/openmetadata-ui/src/main/resources/ui/cypress/common/DomainUtils.js b/openmetadata-ui/src/main/resources/ui/cypress/common/DomainUtils.js index 269d4ca73d04..3891927c7a6e 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/common/DomainUtils.js +++ b/openmetadata-ui/src/main/resources/ui/cypress/common/DomainUtils.js @@ -145,9 +145,7 @@ export const updateAssets = (domainObj) => { cy.get('[data-testid="domain-link"]').should('contain', domainObj.name); - cy.get('[data-testid="app-bar-item-domain"]') - .should('be.visible') - .click({ force: true }); + cy.sidebarClick('app-bar-item-domain'); goToAssetsTab(domainObj); @@ -181,9 +179,7 @@ export const removeAssets = (domainObj) => { cy.get('[data-testid="remove-owner"]').click(); verifyResponseStatusCode('@patchDomain', 200); - cy.get('[data-testid="app-bar-item-domain"]') - .should('be.visible') - .click({ force: true }); + cy.sidebarClick('app-bar-item-domain'); goToAssetsTab(domainObj); cy.contains('Adding a new Asset is easy, just give it a spin!').should( diff --git a/openmetadata-ui/src/main/resources/ui/cypress/common/Entities/UserClass.ts b/openmetadata-ui/src/main/resources/ui/cypress/common/Entities/UserClass.ts index 0ee0c622a6e7..124241ff28cf 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/common/Entities/UserClass.ts +++ b/openmetadata-ui/src/main/resources/ui/cypress/common/Entities/UserClass.ts @@ -31,10 +31,7 @@ class UsersTestClass { } visitUserListPage() { - cy.get('[data-testid="app-bar-item-settings"]') - .should('exist') - .should('be.visible') - .click(); + cy.sidebarClick('app-bar-item-settings'); interceptURL('GET', '/api/v1/users?*', 'getUsers'); cy.get('[data-testid="settings-left-panel"]').contains('Users').click(); } @@ -79,14 +76,15 @@ class UsersTestClass { } checkStewardServicesPermissions() { - cy.get('[data-testid="app-bar-item-explore"]').click(); + cy.sidebarClick('app-bar-item-explore'); Object.values(VISIT_SERVICE_PAGE_DETAILS).forEach((service) => { - cy.get('[data-testid="app-bar-item-settings"]').click(); + cy.sidebarClick('app-bar-item-settings'); + cy.get(`[data-menu-id*="${service.settingsMenuId}"]`).click(); cy.get('[data-testid="add-service-button"] > span').should('not.exist'); }); - cy.get('[data-testid="app-bar-item-explore"]').click(); - cy.get('[data-testid="tables-tab"] > .ant-space').click(); + cy.sidebarClick('app-bar-item-explore'); + cy.get('[data-testid="tables-tab"]').click(); cy.get( '.ant-drawer-title > [data-testid="entity-link"] > .ant-typography' ).click(); diff --git a/openmetadata-ui/src/main/resources/ui/cypress/common/GlossaryUtils.js b/openmetadata-ui/src/main/resources/ui/cypress/common/GlossaryUtils.js index cddc4bbd9e3f..2b570dbf0b96 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/common/GlossaryUtils.js +++ b/openmetadata-ui/src/main/resources/ui/cypress/common/GlossaryUtils.js @@ -23,13 +23,15 @@ import { export const visitGlossaryPage = () => { interceptURL('GET', '/api/v1/glossaries?fields=*', 'getGlossaries'); + cy.sidebarHover(); cy.get('[data-testid="governance"]').click({ animationDistanceThreshold: 20, waitForAnimations: true, }); // Applying force true as the hover over tooltip - cy.get('[data-testid="app-bar-item-glossary"]').click({ force: true }); + + cy.sidebarClick('app-bar-item-glossary'); verifyResponseStatusCode('@getGlossaries', 200); }; diff --git a/openmetadata-ui/src/main/resources/ui/cypress/common/TagUtils.js b/openmetadata-ui/src/main/resources/ui/cypress/common/TagUtils.js index 047dcb9afb9d..446dadf8a0a7 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/common/TagUtils.js +++ b/openmetadata-ui/src/main/resources/ui/cypress/common/TagUtils.js @@ -59,12 +59,13 @@ export const validateForm = () => { export const visitClassificationPage = () => { interceptURL('GET', '/api/v1/tags*', 'getTags'); + cy.sidebarHover(); cy.get('[data-testid="governance"]').click({ animationDistanceThreshold: 20, waitForAnimations: true, }); - cy.get('[data-testid="app-bar-item-tags"]').click(); + cy.sidebarClick('app-bar-item-tags'); verifyResponseStatusCode('@getTags', 200); }; diff --git a/openmetadata-ui/src/main/resources/ui/cypress/common/Utils/CustomProperty.ts b/openmetadata-ui/src/main/resources/ui/cypress/common/Utils/CustomProperty.ts index 423afd48192c..12c8e0aeab83 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/common/Utils/CustomProperty.ts +++ b/openmetadata-ui/src/main/resources/ui/cypress/common/Utils/CustomProperty.ts @@ -41,7 +41,8 @@ export const createCustomPropertyForEntity = ({ }) => { interceptURL('GET', '/api/v1/teams/name/*', 'settingsPage'); - cy.get('[data-testid="app-bar-item-settings"]').click(); + cy.sidebarClick('app-bar-item-settings'); + verifyResponseStatusCode('@settingsPage', 200); interceptURL('GET', `/api/v1/metadata/types/name/*`, 'getEntity'); @@ -80,7 +81,7 @@ export const deleteCustomPropertyForEntity = ({ property: CustomProperty; type: EntityType; }) => { - cy.get('[data-testid="app-bar-item-settings"]').click(); + cy.sidebarClick('app-bar-item-settings'); interceptURL('GET', `/api/v1/metadata/types/name/*`, 'getEntity'); interceptURL('PATCH', `/api/v1/metadata/types/*`, 'patchEntity'); diff --git a/openmetadata-ui/src/main/resources/ui/cypress/common/Utils/Users.ts b/openmetadata-ui/src/main/resources/ui/cypress/common/Utils/Users.ts index 85adf015c8d1..e460ab511842 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/common/Utils/Users.ts +++ b/openmetadata-ui/src/main/resources/ui/cypress/common/Utils/Users.ts @@ -170,10 +170,8 @@ export const permanentDeleteUser = (username: string) => { cy.get('[data-testid="search-error-placeholder"]').should('be.exist'); }; export const visitUserListPage = () => { - cy.get('[data-testid="app-bar-item-settings"]') - .should('exist') - .should('be.visible') - .click(); + cy.sidebarClick('app-bar-item-settings'); + interceptURL('GET', '/api/v1/users?*', 'getUsers'); cy.get('[data-testid="settings-left-panel"]').contains('Users').click(); }; diff --git a/openmetadata-ui/src/main/resources/ui/cypress/common/advancedSearch.js b/openmetadata-ui/src/main/resources/ui/cypress/common/advancedSearch.js index fa88cdb9667e..632b8ea31dcd 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/common/advancedSearch.js +++ b/openmetadata-ui/src/main/resources/ui/cypress/common/advancedSearch.js @@ -229,7 +229,7 @@ export const searchForField = (condition, fieldid, searchCriteria, index) => { export const goToAdvanceSearch = () => { // Navigate to explore page - cy.get('[data-testid="app-bar-item-explore"]').click(); + cy.sidebarClick('app-bar-item-explore'); cy.get('[data-testid="advance-search-button"]').click(); cy.get('[data-testid="reset-btn"]').click(); }; diff --git a/openmetadata-ui/src/main/resources/ui/cypress/common/common.js b/openmetadata-ui/src/main/resources/ui/cypress/common/common.js index 08d46bc7ea62..bdeddb18221e 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/common/common.js +++ b/openmetadata-ui/src/main/resources/ui/cypress/common/common.js @@ -424,9 +424,9 @@ export const deleteCreatedService = ( 'api/v1/teams/name/Organization?fields=*', 'getSettingsPage' ); - cy.get('[data-testid="app-bar-item-settings"]') - .should('be.visible') - .click({ force: true }); + + cy.sidebarClick('app-bar-item-settings'); + verifyResponseStatusCode('@getSettingsPage', 200); // Services page interceptURL('GET', '/api/v1/services/*', 'getServices'); @@ -511,7 +511,8 @@ export const goToAddNewServicePage = (service_type) => { 'getSettingsPage' ); // Click on settings page - cy.get('[data-testid="app-bar-item-settings"]').should('be.visible').click(); + cy.sidebarClick('app-bar-item-settings'); + verifyResponseStatusCode('@getSettingsPage', 200); // Services page interceptURL('GET', '/api/v1/services/*', 'getServiceList'); @@ -966,7 +967,7 @@ export const updateDescriptionForIngestedTables = ( verifyResponseStatusCode('@updateEntity', 200); // re-run ingestion flow - cy.get('[data-testid="app-bar-item-settings"]').should('be.visible').click(); + cy.sidebarClick('app-bar-item-settings'); // Services page cy.get('.ant-menu-title-content').contains(type).should('be.visible').click(); @@ -1140,7 +1141,7 @@ export const visitServiceDetailsPage = ( ); interceptURL('GET', '/api/v1/teams/name/*', 'getOrganization'); - cy.get('[data-testid="app-bar-item-settings"]').click(); + cy.sidebarClick('app-bar-item-settings'); verifyResponseStatusCode('@getOrganization', 200); @@ -1172,7 +1173,7 @@ export const visitServiceDetailsPage = ( export const visitDataModelPage = (dataModelFQN, dataModelName) => { interceptURL('GET', '/api/v1/teams/name/*', 'getOrganization'); - cy.get('[data-testid="app-bar-item-settings"]').click(); + cy.sidebarClick('app-bar-item-settings'); verifyResponseStatusCode('@getOrganization', 200); diff --git a/openmetadata-ui/src/main/resources/ui/cypress/common/serviceUtils.js b/openmetadata-ui/src/main/resources/ui/cypress/common/serviceUtils.js index be5b4717dab7..f0125b5436cb 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/common/serviceUtils.js +++ b/openmetadata-ui/src/main/resources/ui/cypress/common/serviceUtils.js @@ -30,7 +30,8 @@ export const visitServiceDetailsPage = (service, verifyHeader = true) => { 'api/v1/teams/name/Organization?fields=*', 'getSettingsPage' ); - cy.get('[data-testid="app-bar-item-settings"]').click(); + + cy.sidebarClick('app-bar-item-settings'); verifyResponseStatusCode('@getSettingsPage', 200); // Services page diff --git a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Features/DataConsumerRole.spec.js b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Features/DataConsumerRole.spec.js index 0e3e577499ae..df02c8701802 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Features/DataConsumerRole.spec.js +++ b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Features/DataConsumerRole.spec.js @@ -259,11 +259,16 @@ describe('DataConsumer Edit policy should work properly', () => { cy.url().should('eq', `${BASE_URL}/my-data`); // Check CRUD for Glossary + + cy.sidebarHover(); + cy.get(glossary.testid) .should('be.visible') .click({ animationDistanceThreshold: 10 }); if (glossary.subMenu) { cy.get(glossary.subMenu).should('be.visible').click({ force: true }); + + cy.sidebarHoverOutside(); } cy.get('body').click(); diff --git a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Features/IncidentManager.spec.js b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Features/IncidentManager.spec.js index 56937e1b2523..4945b9d62ab4 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Features/IncidentManager.spec.js +++ b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Features/IncidentManager.spec.js @@ -88,9 +88,7 @@ describe.skip('Incident Manager', () => { cy.clickOnLogo(); - cy.get('[data-testid="app-bar-item-settings"]') - .should('be.visible') - .click(); + cy.sidebarClick('app-bar-item-settings'); cy.get('[data-menu-id*="databases"]').should('be.visible').click(); cy.intercept('/api/v1/services/ingestionPipelines?*').as('ingestionData'); interceptURL( @@ -214,8 +212,9 @@ describe.skip('Incident Manager', () => { }); it('Assign incident to user', () => { + cy.sidebarHover(); cy.get("[data-testid='data-quality'").click(); - cy.get("[data-testid='app-bar-item-incident-manager'").click(); + cy.sidebarClick('app-bar-item-incident-manager'); cy.get(`[data-testid="test-case-${NEW_TABLE_TEST_CASE.name}"]`).should( 'be.visible' ); @@ -252,8 +251,9 @@ describe.skip('Incident Manager', () => { 'getTestCase' ); interceptURL('GET', '/api/v1/feed?entityLink=*&type=Task', 'getTaskFeed'); + cy.sidebarHover(); cy.get("[data-testid='data-quality'").click(); - cy.get("[data-testid='app-bar-item-incident-manager'").click(); + cy.sidebarClick('app-bar-item-incident-manager'); cy.get(`[data-testid="test-case-${NEW_TABLE_TEST_CASE.name}"]`).click(); verifyResponseStatusCode('@getTestCase', 200); cy.get('[data-testid="issue"]').click(); @@ -285,8 +285,9 @@ describe.skip('Incident Manager', () => { 'getTestCase' ); interceptURL('GET', '/api/v1/feed?entityLink=*&type=Task', 'getTaskFeed'); + cy.sidebarHover(); cy.get("[data-testid='data-quality'").click(); - cy.get("[data-testid='app-bar-item-incident-manager'").click(); + cy.sidebarClick('app-bar-item-incident-manager'); cy.get(`[data-testid="test-case-${NEW_TABLE_TEST_CASE.name}"]`).click(); verifyResponseStatusCode('@getTestCase', 200); cy.get('[data-testid="issue"]').click(); diff --git a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Features/SchemaSearch.spec.js b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Features/SchemaSearch.spec.js index 56eec3512727..301498abba25 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Features/SchemaSearch.spec.js +++ b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Features/SchemaSearch.spec.js @@ -86,9 +86,9 @@ describe('Schema search', () => { 'api/v1/teams/name/Organization?fields=*', 'getSettingsPage' ); - cy.get('[data-testid="app-bar-item-settings"]') - .should('be.visible') - .click(); + + cy.sidebarClick('app-bar-item-settings'); + verifyResponseStatusCode('@getSettingsPage', 200); // Services page interceptURL('GET', '/api/v1/services/*', 'getServices'); diff --git a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Features/TeamsHierarchy.spec.js b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Features/TeamsHierarchy.spec.js index c29cc2f0203a..319e28af9f7a 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Features/TeamsHierarchy.spec.js +++ b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Features/TeamsHierarchy.spec.js @@ -38,9 +38,8 @@ describe('Add nested teams and test TeamsSelectable', () => { beforeEach(() => { cy.login(); - cy.get('[data-testid="app-bar-item-settings"]') - .should('be.visible') - .click(); + cy.sidebarClick('app-bar-item-settings'); + interceptURL('GET', '/api/v1/teams/name/*', 'getOrganization'); interceptURL('GET', '/api/v1/permissions/team/name/*', 'getPermissions'); // Clicking on teams diff --git a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Flow/AddRoleAndAssignToUser.spec.js b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Flow/AddRoleAndAssignToUser.spec.js index e229470cd064..78a5836b299c 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Flow/AddRoleAndAssignToUser.spec.js +++ b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Flow/AddRoleAndAssignToUser.spec.js @@ -28,9 +28,7 @@ describe('Test Add role and assign it to the user', () => { cy.login(); interceptURL('GET', '*api/v1/roles*', 'getRoles'); interceptURL('GET', '/api/v1/users?*', 'usersPage'); - cy.get('[data-testid="app-bar-item-settings"]') - .should('be.visible') - .click(); + cy.sidebarClick('app-bar-item-settings'); }); it('Create role', () => { diff --git a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Flow/AdvancedSearchQuickFilters.spec.js b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Flow/AdvancedSearchQuickFilters.spec.js index 0598d98276ce..6f902c73dac4 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Flow/AdvancedSearchQuickFilters.spec.js +++ b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Flow/AdvancedSearchQuickFilters.spec.js @@ -35,7 +35,7 @@ describe(`Advanced search quick filters should work properly for assets`, () => it(`should show the quick filters for respective assets`, () => { // Navigate to explore page - cy.get('[data-testid="app-bar-item-explore"]').click(); + cy.sidebarClick('app-bar-item-explore'); QUICK_FILTERS_BY_ASSETS.map((asset) => { cy.get(`[data-testid="${asset.tab}"]`).scrollIntoView().click(); @@ -52,7 +52,7 @@ describe(`Advanced search quick filters should work properly for assets`, () => const asset = QUICK_FILTERS_BY_ASSETS[0]; // Navigate to explore page - cy.get('[data-testid="app-bar-item-explore"]').click(); + cy.sidebarClick('app-bar-item-explore'); cy.get(`[data-testid="${asset.tab}"]`).scrollIntoView().click(); asset.filters diff --git a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Flow/Collect.spec.js b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Flow/Collect.spec.js index dbfa2fbfa38a..1a9bbe54526e 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Flow/Collect.spec.js +++ b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Flow/Collect.spec.js @@ -66,6 +66,7 @@ describe('Collect end point should work properly', () => { Object.values(PAGES).map((page) => { it(`Visit ${page.name} page should trigger collect API`, () => { + cy.sidebarHover(); cy.get(page.mainMenuId) .should('be.visible') .click({ animationDistanceThreshold: 10 }); @@ -74,6 +75,7 @@ describe('Collect end point should work properly', () => { cy.wait(500); cy.get(page.subMenu).should('be.visible').click({ force: true }); } + cy.sidebarHoverOutside(); assertCollectEndPoint(); }); }); diff --git a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Flow/PersonaFlow.spec.js b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Flow/PersonaFlow.spec.js index 228b2e2e9f1e..dd6a754c3635 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Flow/PersonaFlow.spec.js +++ b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Flow/PersonaFlow.spec.js @@ -78,7 +78,8 @@ describe('Persona operations', () => { cy.login(); interceptURL('GET', '/api/v1/teams/name/*', 'settingsPage'); - cy.get('[data-testid="app-bar-item-settings"]').click(); + cy.sidebarClick('app-bar-item-settings'); + verifyResponseStatusCode('@settingsPage', 200); cy.get('[data-testid="settings-left-panel"]').should('be.visible'); diff --git a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/Alerts.spec.js b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/Alerts.spec.js index ad2d3592bf09..ea2da021d7db 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/Alerts.spec.js +++ b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/Alerts.spec.js @@ -62,10 +62,7 @@ describe.skip('Alerts page should work properly', () => { interceptURL('POST', '/api/v1/events/subscriptions', 'createAlert'); interceptURL('GET', `/api/v1/search/query?q=*`, 'getSearchResult'); cy.login(); - cy.get('[data-testid="app-bar-item-settings"]') - .should('exist') - .and('be.visible') - .click(); + cy.sidebarClick('app-bar-item-settings'); interceptURL('GET', '/api/v1/events/subscriptions?*', 'alertsPage'); cy.get('[data-testid="global-setting-left-panel"]') .contains('Alerts') diff --git a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/Bots.spec.js b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/Bots.spec.js index ff4e2facd838..67be0b148f07 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/Bots.spec.js +++ b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/Bots.spec.js @@ -70,10 +70,7 @@ const revokeToken = () => { describe('Bots Page should work properly', () => { beforeEach(() => { cy.login(); - cy.get('[data-testid="app-bar-item-settings"]') - .should('exist') - .should('be.visible') - .click(); + cy.sidebarClick('app-bar-item-settings'); interceptURL( 'GET', 'api/v1/bots?limit=*&include=non-deleted', diff --git a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/CustomLogoConfig.spec.js b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/CustomLogoConfig.spec.js index 412e1cb01e0c..c4cf70856cc4 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/CustomLogoConfig.spec.js +++ b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/CustomLogoConfig.spec.js @@ -26,7 +26,7 @@ describe('Custom Logo Config', () => { beforeEach(() => { cy.login(); - cy.get('[data-testid="app-bar-item-settings"]').click(); + cy.sidebarClick('app-bar-item-settings'); interceptURL( 'GET', diff --git a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/Customproperties.spec.js b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/Customproperties.spec.js index b4ac3395c745..e9027a96796e 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/Customproperties.spec.js +++ b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/Customproperties.spec.js @@ -24,10 +24,7 @@ describe('Custom Properties should work properly', () => { beforeEach(() => { cy.login(); interceptURL('GET', '/api/v1/teams/name/*', 'settingsPage'); - - cy.get('[data-testid="app-bar-item-settings"]') - .should('be.visible') - .click(); + cy.sidebarClick('app-bar-item-settings'); verifyResponseStatusCode('@settingsPage', 200); cy.get('[data-testid="settings-left-panel"]').should('be.visible'); }); @@ -60,7 +57,7 @@ describe('Custom Properties should work properly', () => { ); // Navigating back to custom properties page - cy.get('[data-testid="app-bar-item-settings"]').click(); + cy.sidebarClick('app-bar-item-settings'); cy.get(`[data-menu-id*="customAttributes.${entity.name}"]`) .scrollIntoView() .click(); @@ -131,9 +128,7 @@ describe('Custom Properties should work properly', () => { ); // Navigating back to custom properties page - cy.get('[data-testid="app-bar-item-settings"]') - .should('be.visible') - .click(); + cy.sidebarClick('app-bar-item-settings'); // Selecting the entity cy.get(`[data-menu-id*="customAttributes.${entity.name}"]`) .scrollIntoView() @@ -207,9 +202,7 @@ describe('Custom Properties should work properly', () => { ); // Navigating back to custom properties page - cy.get('[data-testid="app-bar-item-settings"]') - .should('be.visible') - .click(); + cy.sidebarClick('app-bar-item-settings'); cy.get(`[data-menu-id*="customAttributes.${entity.name}"]`) .scrollIntoView() .should('be.visible') @@ -280,7 +273,7 @@ describe('Custom Properties should work properly', () => { ); // Navigating to explore page - cy.get('[data-testid="app-bar-item-explore"]').click(); + cy.sidebarClick('app-bar-item-explore'); interceptURL( 'GET', `/api/v1/metadata/types/name/glossaryTerm*`, diff --git a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/DataInsight.spec.js b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/DataInsight.spec.js index f1f9357d7c1c..a69ed0ef230d 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/DataInsight.spec.js +++ b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/DataInsight.spec.js @@ -93,13 +93,13 @@ describe('Data Insight feature', () => { }); it('Initial setup', () => { - cy.get('[data-testid="app-bar-item-data-insight"]').click(); + cy.sidebarClick('app-bar-item-data-insight'); verifyResponseStatusCode('@dataInsightsChart', 200); deleteKpiRequest(); }); it('Create description and owner KPI', () => { - cy.get('[data-testid="app-bar-item-data-insight"]').click(); + cy.sidebarClick('app-bar-item-data-insight'); verifyResponseStatusCode('@dataInsightsChart', 200); cy.get('[data-menu-id*="kpi"]').click(); KPI_DATA.map((data) => { @@ -126,7 +126,7 @@ describe('Data Insight feature', () => { '/api/v1/apps/trigger/DataInsightsApplication', 'triggerPipeline' ); - cy.get('[data-testid="app-bar-item-settings"]').click(); + cy.sidebarClick('app-bar-item-settings'); cy.get('[data-menu-id*="integrations.apps"]').scrollIntoView().click(); verifyResponseStatusCode('@apps', 200); cy.get( @@ -144,7 +144,7 @@ describe('Data Insight feature', () => { }); it('Verifying Data assets tab', () => { - cy.get('[data-testid="app-bar-item-data-insight"]').click(); + cy.sidebarClick('app-bar-item-data-insight'); verifyResponseStatusCode('@dataInsightsChart', 200); cy.get('[data-testid="search-dropdown-Team"]').should('be.visible'); cy.get('[data-testid="search-dropdown-Tier"]').should('be.visible'); @@ -170,7 +170,7 @@ describe('Data Insight feature', () => { }); it('Verifying App analytics tab', () => { - cy.get('[data-testid="app-bar-item-data-insight"]').click(); + cy.sidebarClick('app-bar-item-data-insight'); verifyResponseStatusCode('@dataInsightsChart', 200); cy.get('[data-menu-id*="app-analytics"]').click(); verifyResponseStatusCode('@dataInsightsChart', 200); @@ -192,7 +192,7 @@ describe('Data Insight feature', () => { }); it('Verifying KPI tab', () => { - cy.get('[data-testid="app-bar-item-data-insight"]').click(); + cy.sidebarClick('app-bar-item-data-insight'); verifyResponseStatusCode('@dataInsightsChart', 200); cy.get('[data-menu-id*="kpi"]').click(); verifyResponseStatusCode('@dataInsightsChart', 200); @@ -210,7 +210,7 @@ describe('Data Insight feature', () => { it('Update KPI', () => { interceptURL('GET', '/api/v1/kpi/name/*', 'fetchKpiByName'); interceptURL('PATCH', '/api/v1/kpi/*', 'updateKpi'); - cy.get('[data-testid="app-bar-item-data-insight"]').click(); + cy.sidebarClick('app-bar-item-data-insight'); verifyResponseStatusCode('@dataInsightsChart', 200); cy.get('[data-menu-id*="kpi"]').click(); verifyResponseStatusCode('@dataInsightsChart', 200); @@ -233,7 +233,7 @@ describe('Data Insight feature', () => { '/api/v1/kpi/*?hardDelete=true&recursive=false', 'deleteKpi' ); - cy.get('[data-testid="app-bar-item-data-insight"]').click(); + cy.sidebarClick('app-bar-item-data-insight'); verifyResponseStatusCode('@dataInsightsChart', 200); cy.get('[data-menu-id*="kpi"]').click(); verifyResponseStatusCode('@dataInsightsChart', 200); diff --git a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/DataInsightAlert.spec.js b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/DataInsightAlert.spec.js index 6c279d2832d6..4cfb70fbd8a3 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/DataInsightAlert.spec.js +++ b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/DataInsightAlert.spec.js @@ -30,11 +30,7 @@ const dataInsightReport = { describe.skip('Data Insight Alert', () => { beforeEach(() => { cy.login(); - - cy.get('[data-testid="app-bar-item-settings"]') - .should('exist') - .and('be.visible') - .click(); + cy.sidebarClick('app-bar-item-settings'); interceptURL( 'GET', diff --git a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/DataInsightSettings.spec.js b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/DataInsightSettings.spec.js index c6edd8752447..51c050b6e042 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/DataInsightSettings.spec.js +++ b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/DataInsightSettings.spec.js @@ -18,7 +18,8 @@ describe('Data Insight settings page should work properly', () => { cy.login(); interceptURL('GET', '/api/v1/teams/name/*', 'settingsPage'); - cy.get('[data-testid="app-bar-item-settings"]').click(); + cy.sidebarClick('app-bar-item-settings'); + verifyResponseStatusCode('@settingsPage', 200); cy.get('[data-testid="settings-left-panel"]').should('be.visible'); diff --git a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/DataQualityAndProfiler.spec.js b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/DataQualityAndProfiler.spec.js index 5b35e337d9c7..38d4db01b11a 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/DataQualityAndProfiler.spec.js +++ b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/DataQualityAndProfiler.spec.js @@ -103,8 +103,15 @@ const visitTestSuiteDetailsPage = (testSuiteName) => { 'testSuite' ); interceptURL('GET', '/api/v1/dataQuality/testCases?fields=*', 'testCase'); + + cy.sidebarHover(); + cy.get('[data-testid="data-quality"]').click(); - cy.get('[data-testid="app-bar-item-data-contract"]').click(); + + cy.sidebarClick('app-bar-item-data-contract'); + + cy.sidebarHoverOutside(); + cy.get('[data-testid="by-test-suites"]').click(); verifyResponseStatusCode('@testSuite', 200); clickOnTestSuite(testSuiteName); @@ -194,9 +201,8 @@ describe('Data Quality and Profiler should work properly', () => { cy.clickOnLogo(); - cy.get('[data-testid="app-bar-item-settings"]') - .should('be.visible') - .click(); + cy.sidebarClick('app-bar-item-settings'); + cy.get('[data-menu-id*="services.databases"]').should('be.visible').click(); cy.intercept('/api/v1/services/ingestionPipelines?*').as('ingestionData'); interceptURL( @@ -526,8 +532,15 @@ describe('Data Quality and Profiler should work properly', () => { '/api/v1/search/query?q=*&index=test_case_search_index*', 'getTestCase' ); + + cy.sidebarHover(); + cy.get('[data-testid="data-quality"]').click(); - cy.get('[data-testid="app-bar-item-data-contract"]').click(); + + cy.sidebarClick('app-bar-item-data-contract'); + + cy.sidebarHoverOutside(); + cy.get('[data-testid="by-test-suites"]').click(); verifyResponseStatusCode('@testSuite', 200); cy.get('[data-testid="add-test-suite-btn"]').click(); @@ -786,8 +799,15 @@ describe('Data Quality and Profiler should work properly', () => { it('Update displayName of test case', () => { interceptURL('GET', '/api/v1/dataQuality/testCases?*', 'getTestCase'); + + cy.sidebarHover(); + cy.get('[data-testid="data-quality"]').click(); - cy.get('[data-testid="app-bar-item-data-contract"]').click(); + + cy.sidebarClick('app-bar-item-data-contract'); + + cy.sidebarHoverOutside(); + cy.get('[data-testid="by-test-cases"]').click(); verifyResponseStatusCode('@getTestCase', 200); interceptURL( diff --git a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/Domains.spec.js b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/Domains.spec.js index a255ac8f46bc..f040f52e1dce 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/Domains.spec.js +++ b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/Domains.spec.js @@ -34,9 +34,7 @@ describe('Domain page should work properly', () => { beforeEach(() => { cy.login(); - cy.get('[data-testid="app-bar-item-domain"]').click({ - waitForAnimations: true, - }); + cy.sidebarClick('app-bar-item-domain'); }); it('Create new domain flow should work properly', () => { @@ -61,18 +59,14 @@ describe('Domain page should work properly', () => { it('Create new data product should work properly', () => { DOMAIN_1.dataProducts.forEach((dataProduct) => { createDataProducts(dataProduct, DOMAIN_1); - cy.get('[data-testid="app-bar-item-domain"]').click({ - waitForAnimations: true, - }); + cy.sidebarClick('app-bar-item-domain'); }); }); it('Add data product assets using asset selection modal should work properly', () => { DOMAIN_2.dataProducts.forEach((dp) => { createDataProducts(dp, DOMAIN_2); - cy.get('[data-testid="app-bar-item-domain"]').click({ - waitForAnimations: true, - }); + cy.sidebarClick('app-bar-item-domain'); }); addAssetsToDataProduct(DOMAIN_2.dataProducts[0], DOMAIN_2); @@ -81,9 +75,7 @@ describe('Domain page should work properly', () => { it('Add data product assets using asset selection modal with separate domain and dp having space', () => { DOMAIN_3.dataProducts.forEach((dp) => { createDataProducts(dp, DOMAIN_3); - cy.get('[data-testid="app-bar-item-domain"]').click({ - waitForAnimations: true, - }); + cy.sidebarClick('app-bar-item-domain'); }); addAssetsToDataProduct(DOMAIN_3.dataProducts[0], DOMAIN_3); @@ -104,7 +96,7 @@ describe('Domain page should work properly', () => { 'tableSearchQuery' ); - cy.get('[data-testid="app-bar-item-explore"]').click(); + cy.sidebarClick('app-bar-item-explore'); verifyResponseStatusCode('@tableSearchQuery', 200); }); 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 95dd1017264b..e23fbe36d588 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 @@ -584,16 +584,14 @@ const voteGlossary = (isGlossary) => { const goToGlossaryPage = () => { interceptURL('GET', '/api/v1/glossaryTerms*', 'getGlossaryTerms'); interceptURL('GET', '/api/v1/glossaries?fields=*', 'fetchGlossaries'); + + cy.sidebarHover(); cy.get('[data-testid="governance"]').click({ animationDistanceThreshold: 20, + waitForAnimations: true, }); - // Clicking on Glossary - cy.get('.govern-menu').then(($el) => { - cy.wrap($el) - .find('[data-testid="app-bar-item-glossary"]') - .click({ force: true }); - }); + cy.sidebarClick('app-bar-item-glossary'); }; const approveGlossaryTermWorkflow = ({ glossary, glossaryTerm }) => { @@ -1073,8 +1071,8 @@ describe('Glossary page should work properly', () => { cy.get( '[data-testid="glossary-tags-0"] > [data-testid="tags-wrapper"] > [data-testid="glossary-container"] [data-testid="icon"]' ).should('be.visible'); - cy.get('[data-testid="governance"]').click(); - cy.get('[data-testid="app-bar-item-glossary"]').click({ force: true }); + + goToGlossaryPage(); cy.get('.ant-menu-item').contains(NEW_GLOSSARY_1.name).click(); @@ -1166,8 +1164,7 @@ describe('Glossary page should work properly', () => { .should('not.contain', name) .and('not.contain', 'Personal'); - cy.get('[data-testid="governance"]').click(); - cy.get('[data-testid="app-bar-item-glossary"]').click({ force: true }); + goToGlossaryPage(); selectActiveGlossary(NEW_GLOSSARY_1.name); diff --git a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/LoginConfiguration.ts b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/LoginConfiguration.ts index df4fa2a32e0f..2987752e8bb4 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/LoginConfiguration.ts +++ b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/LoginConfiguration.ts @@ -13,7 +13,8 @@ describe('template spec', () => { beforeEach(() => { cy.login(); - cy.get('[data-testid="app-bar-item-settings"]').click(); + + cy.sidebarClick('app-bar-item-settings'); cy.get('[data-testid="settings-left-panel"]') .contains('Login Configuration') diff --git a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/Policies.spec.js b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/Policies.spec.js index 14e9a4350616..e82ad1d0dbbd 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/Policies.spec.js +++ b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/Policies.spec.js @@ -100,9 +100,7 @@ describe('Policy page should work properly', () => { cy.login(); cy.intercept('GET', '*api/v1/policies*').as('getPolicies'); - cy.get('[data-testid="app-bar-item-settings"]') - .should('be.visible') - .click(); + cy.sidebarClick('app-bar-item-settings'); cy.get('[data-testid="settings-left-panel"]') .contains('Policies') diff --git a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/Roles.spec.js b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/Roles.spec.js index 94a998433bc5..05873e4dab79 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/Roles.spec.js +++ b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/Roles.spec.js @@ -61,9 +61,7 @@ describe('Roles page should work properly', () => { interceptURL('GET', '*api/v1/roles*', 'getRoles'); - cy.get('[data-testid="app-bar-item-settings"]') - .should('be.visible') - .click(); + cy.sidebarClick('app-bar-item-settings'); cy.get('[data-testid="settings-left-panel"]') .contains('Roles') diff --git a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/SearchIndexDetails.spec.js b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/SearchIndexDetails.spec.js index 2f93af6e7b8d..dcb59105de9d 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/SearchIndexDetails.spec.js +++ b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/SearchIndexDetails.spec.js @@ -189,7 +189,8 @@ describe('Prerequisite for data steward role tests', () => { cy.login(); // Assign data steward role to the created user - cy.get('[data-testid="app-bar-item-settings"]').click(); + + cy.sidebarClick('app-bar-item-settings'); interceptURL('GET', `/api/v1/users?*`, 'getUsersList'); diff --git a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/Service.spec.js b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/Service.spec.js index ed4012e66b44..c882f98f4dee 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/Service.spec.js +++ b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/Service.spec.js @@ -39,9 +39,7 @@ describe('Services page should work properly', () => { cy.login(); // redirecting to services page - cy.get('[data-testid="app-bar-item-settings"]') - .should('be.visible') - .click(); + cy.sidebarClick('app-bar-item-settings'); cy.get('[data-testid="settings-left-panel"]') .contains('Database') diff --git a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/Teams.spec.js b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/Teams.spec.js index 6097443c8100..2a7fc2ea6490 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/Teams.spec.js +++ b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/Teams.spec.js @@ -53,7 +53,7 @@ describe('Teams flow should work properly', () => { interceptURL('GET', `/api/v1/permissions/team/name/*`, 'permissions'); cy.login(); - cy.get('[data-testid="app-bar-item-settings"]').click(); + cy.sidebarClick('app-bar-item-settings'); // Clicking on teams cy.get('[data-testid="settings-left-panel"]').contains('Teams').click(); diff --git a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/Users.spec.ts b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/Users.spec.ts index e6313e514e35..511332749af6 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/Users.spec.ts +++ b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/Users.spec.ts @@ -11,6 +11,7 @@ * limitations under the License. */ // eslint-disable-next-line spaced-comment +import { interceptURL, verifyResponseStatusCode } from '../../common/common'; import UsersTestClass from '../../common/Entities/UserClass'; import { visitEntityDetailsPage } from '../../common/Utils/Entity'; import { addOwner, removeOwner } from '../../common/Utils/Owner'; @@ -24,7 +25,6 @@ import { updateExpiration, visitUserListPage, } from '../../common/Utils/Users'; -import { interceptURL, verifyResponseStatusCode } from '../../common/common'; import { EntityType } from '../../constants/Entity.interface'; import { @@ -110,9 +110,11 @@ describe('User with different Roles', () => { cy.url().should('eq', `${BASE_URL}/my-data`); // Check CRUD for Glossary + cy.sidebarHover(); + cy.get(glossary.testid) .should('be.visible') - .click({ animationDistanceThreshold: 10 }); + .click({ animationDistanceThreshold: 10, waitForAnimations: true }); if (glossary.subMenu) { cy.get(glossary.subMenu).should('be.visible').click({ force: true }); } @@ -123,7 +125,7 @@ describe('User with different Roles', () => { // Check CRUD for Tags cy.get(tag.testid) .should('be.visible') - .click({ animationDistanceThreshold: 10 }); + .click({ animationDistanceThreshold: 10, waitForAnimations: true }); if (tag.subMenu) { cy.get(tag.subMenu).should('be.visible').click({ force: true }); } diff --git a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/redirections.spec.js b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/redirections.spec.js index bc1f9172a0d8..732a4fd93271 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/redirections.spec.js +++ b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/redirections.spec.js @@ -45,6 +45,7 @@ describe('Redirection link should work properly', () => { it('Check redirection links on settings page', () => { cy.get(NAVBAR_DETAILS.settings.testid).should('be.visible').click(); Object.values(SETTINGS_LEFT_PANEL).map((settingsLeftPanel) => { + cy.sidebarHoverOutside(); cy.get(settingsLeftPanel.testid) .scrollIntoView() .should('be.visible') diff --git a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Service/redshiftWithDBT.spec.js b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Service/redshiftWithDBT.spec.js index c8730e36199c..cba926a82420 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Service/redshiftWithDBT.spec.js +++ b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Service/redshiftWithDBT.spec.js @@ -106,9 +106,7 @@ describe('RedShift Ingestion', () => { '/api/v1/services/ingestionPipelines/*/pipelineStatus?startTs=*&endTs=*', 'pipelineStatus' ); - cy.get('[data-testid="app-bar-item-settings"]') - .should('be.visible') - .click({ force: true }); + cy.sidebarClick('app-bar-item-settings'); verifyResponseStatusCode('@getSettingsPage', 200); // Services page interceptURL('GET', '/api/v1/services/*', 'getServices'); @@ -225,11 +223,10 @@ describe('RedShift Ingestion', () => { `/api/v1/tags?*parent=${DBT.classification}*`, 'getTagList' ); + cy.sidebarHover(); cy.get('[data-testid="governance"]').click(); - cy.get('[data-testid="app-bar-item-tags"]').click({ - waitForAnimations: true, - }); + cy.sidebarClick('app-bar-item-tags'); verifyResponseStatusCode('@fetchClassifications', 200); diff --git a/openmetadata-ui/src/main/resources/ui/cypress/support/commands.js b/openmetadata-ui/src/main/resources/ui/cypress/support/commands.js index 40311feb3a13..ae39628c7b13 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/support/commands.js +++ b/openmetadata-ui/src/main/resources/ui/cypress/support/commands.js @@ -142,6 +142,14 @@ Cypress.Commands.add('clickOutside', function () { return cy.get('body').click(0, 0); // 0,0 here are the x and y coordinates }); +Cypress.Commands.add('sidebarHover', function () { + return cy.get('[data-testid="left-sidebar"]').trigger('mouseover'); // trigger mouseover event inside the sidebar +}); + +Cypress.Commands.add('sidebarHoverOutside', function () { + return cy.get('[data-testid="left-sidebar"]').trigger('mouseout'); // trigger mouseout event outside the sidebar +}); + Cypress.Commands.add('logout', () => { interceptURL('POST', '/api/v1/users/logout', 'logoutUser'); cy.get('[data-testid="app-bar-item-logout"]').scrollIntoView().click(); @@ -154,3 +162,11 @@ Cypress.Commands.add('logout', () => { cy.url().should('eq', `${BASE_URL}/signin`); Cypress.session.clearAllSavedSessions(); }); + +Cypress.Commands.add('sidebarClick', (id) => { + cy.get(`[data-testid="${id}"]`).click({ + animationDistanceThreshold: 20, + waitForAnimations: true, + }); + cy.sidebarHoverOutside(); +}); diff --git a/openmetadata-ui/src/main/resources/ui/src/assets/svg/ic-bulb.svg b/openmetadata-ui/src/main/resources/ui/src/assets/svg/ic-bulb.svg deleted file mode 100644 index ad32999e4854..000000000000 --- a/openmetadata-ui/src/main/resources/ui/src/assets/svg/ic-bulb.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/openmetadata-ui/src/main/resources/ui/src/assets/svg/ic-data-contract.svg b/openmetadata-ui/src/main/resources/ui/src/assets/svg/ic-data-contract.svg index b3f2d8ba7318..aee9288e77c8 100644 --- a/openmetadata-ui/src/main/resources/ui/src/assets/svg/ic-data-contract.svg +++ b/openmetadata-ui/src/main/resources/ui/src/assets/svg/ic-data-contract.svg @@ -1,9 +1,22 @@ - - - - - - - - - \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + diff --git a/openmetadata-ui/src/main/resources/ui/src/assets/svg/ic-incident-manager.svg b/openmetadata-ui/src/main/resources/ui/src/assets/svg/ic-incident-manager.svg new file mode 100644 index 000000000000..bb49797f737d --- /dev/null +++ b/openmetadata-ui/src/main/resources/ui/src/assets/svg/ic-incident-manager.svg @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/openmetadata-ui/src/main/resources/ui/src/components/AppContainer/AppContainer.tsx b/openmetadata-ui/src/main/resources/ui/src/components/AppContainer/AppContainer.tsx index dfbba89d5be5..a694a946b5ee 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/AppContainer/AppContainer.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/AppContainer/AppContainer.tsx @@ -11,20 +11,19 @@ * limitations under the License. */ import { Layout } from 'antd'; -import { Content, Header } from 'antd/lib/layout/layout'; -import Sider from 'antd/lib/layout/Sider'; import { isEmpty } from 'lodash'; import React from 'react'; import { Redirect, Route, Switch } from 'react-router-dom'; -import Appbar from '../../components/AppBar/Appbar'; -import AuthenticatedAppRouter from '../../components/AppRouter/AuthenticatedAppRouter'; -import LeftSidebar from '../../components/MyData/LeftSidebar/LeftSidebar.component'; import { ROUTES } from '../../constants/constants'; import SignUpPage from '../../pages/SignUp/SignUpPage'; +import Appbar from '../AppBar/Appbar'; +import AuthenticatedAppRouter from '../AppRouter/AuthenticatedAppRouter'; import { useAuthContext } from '../Auth/AuthProviders/AuthProvider'; +import LeftSidebar from '../MyData/LeftSidebar/LeftSidebar.component'; import './app-container.less'; const AppContainer = () => { + const { Header, Sider, Content } = Layout; const { currentUser } = useAuthContext(); return ( @@ -34,13 +33,13 @@ const AppContainer = () => { -
- -
- - - - + + + + +
+ +
diff --git a/openmetadata-ui/src/main/resources/ui/src/components/AppContainer/app-container.less b/openmetadata-ui/src/main/resources/ui/src/components/AppContainer/app-container.less index 870fef023404..46080941f615 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/AppContainer/app-container.less +++ b/openmetadata-ui/src/main/resources/ui/src/components/AppContainer/app-container.less @@ -37,8 +37,8 @@ } } .left-sidebar-col { - overflow: hidden; padding-right: 0 !important; + z-index: 999; .left-panel-card { border-radius: 0 !important; border-top: 0; diff --git a/openmetadata-ui/src/main/resources/ui/src/components/MyData/LeftSidebar/LeftSidebar.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/MyData/LeftSidebar/LeftSidebar.component.tsx index f77044dea181..6a1833009e09 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/MyData/LeftSidebar/LeftSidebar.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/MyData/LeftSidebar/LeftSidebar.component.tsx @@ -10,14 +10,20 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { Button, Col, Menu, Row, Tooltip, Typography } from 'antd'; +import { Button, Col, Menu, MenuProps, Row, Typography } from 'antd'; import Modal from 'antd/lib/modal/Modal'; -import React, { useMemo, useState } from 'react'; +import classNames from 'classnames'; +import { noop } from 'lodash'; +import React, { useCallback, useMemo, useState } from 'react'; import { useTranslation } from 'react-i18next'; -import { ReactComponent as LogoutIcon } from '../../../assets/svg/logout.svg'; -import { SETTING_ITEM } from '../../../constants/LeftSidebar.constants'; +import { Link } from 'react-router-dom'; +import { + LOGOUT_ITEM, + SETTING_ITEM, +} from '../../../constants/LeftSidebar.constants'; import leftSidebarClassBase from '../../../utils/LeftSidebarClassBase'; import { useAuthContext } from '../../Auth/AuthProviders/AuthProvider'; +import BrandImage from '../../common/BrandImage/BrandImage'; import './left-sidebar.less'; import LeftSidebarItem from './LeftSidebarItem.component'; @@ -25,102 +31,114 @@ const LeftSidebar = () => { const { t } = useTranslation(); const { onLogoutHandler } = useAuthContext(); const [showConfirmLogoutModal, setShowConfirmLogoutModal] = useState(false); + const [isSidebarCollapsed, setIsSidebarCollapsed] = useState(true); - const subMenuItemSelected = useMemo(() => { - if (location.pathname.startsWith('/glossary')) { - return ['glossary']; - } else if (location.pathname.startsWith('/tags')) { - return ['tags']; - } else if (location.pathname.startsWith('/incident-manager')) { - return ['incident-manager']; - } else if (location.pathname.startsWith('/data-quality')) { - return ['data-contract']; - } + const sideBarItems = leftSidebarClassBase.getSidebarItems(); - return []; - }, [location.pathname]); + const selectedKeys = useMemo(() => { + const pathArray = location.pathname.split('/').splice(0, 2).join('/'); - const sideBarItems = leftSidebarClassBase.getSidebarItems(); - const SideBarElements = leftSidebarClassBase.getSidebarElements(); + return [pathArray]; + }, [location.pathname]); - const handleLogoutClick = () => { + const handleLogoutClick = useCallback(() => { setShowConfirmLogoutModal(true); - }; + }, []); const hideConfirmationModal = () => { setShowConfirmLogoutModal(false); }; - return ( -
- - {sideBarItems.map((item) => { - const Icon = item.icon; + const TOP_SIDEBAR_MENU_ITEMS: MenuProps['items'] = useMemo(() => { + return [ + ...sideBarItems.map((item) => { + return { + key: item.key, + label: , + children: item.children?.map((item) => { + return { + key: item.key, + label: , + }; + }), + }; + }), + ]; + }, []); - return ( - - {item.children ? ( - - {item.label} - - }> - - - ), - children: item.children.map((child) => { - return { - key: child.key, - label: , - }; - }), - }, - ]} - mode="vertical" - selectedKeys={subMenuItemSelected} - triggerSubMenuAction="click" - /> - ) : ( - - )} - - ); - })} + const LOWER_SIDEBAR_TOP_SIDEBAR_MENU_ITEMS: MenuProps['items'] = useMemo( + () => + [SETTING_ITEM, LOGOUT_ITEM].map((item) => ({ + key: item.key, + label: ( + + ), + })), + [handleLogoutClick] + ); - {SideBarElements && } - - - - + const handleMouseOver = useCallback(() => { + if (!isSidebarCollapsed) { + return; + } + setIsSidebarCollapsed(false); + }, [isSidebarCollapsed]); + + const handleMouseOut = useCallback(() => { + setIsSidebarCollapsed(true); + }, []); + + return ( +
+ + + + + - - - {t('label.logout')} - - }> -
- -
-
+ + + + + + + {showConfirmLogoutModal && ( void; }; } const LeftSidebarItem = ({ - data: { key, label, icon, redirect_url, dataTestId, isBeta }, + data: { label, redirect_url, dataTestId, icon, isBeta, onClick }, }: LeftSidebarItemProps) => { const { t } = useTranslation(); - const Icon = icon; - return ( - +
+ {label} - }> - + {isBeta && ( )} - - - +
+ + ) : ( +
+ + {label} +
); }; diff --git a/openmetadata-ui/src/main/resources/ui/src/components/MyData/LeftSidebar/LeftSidebarItem.test.tsx b/openmetadata-ui/src/main/resources/ui/src/components/MyData/LeftSidebar/LeftSidebarItem.test.tsx index d3235286ad6e..28e7ff8b14f3 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/MyData/LeftSidebar/LeftSidebarItem.test.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/MyData/LeftSidebar/LeftSidebarItem.test.tsx @@ -10,22 +10,77 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { render, screen } from '@testing-library/react'; +import { fireEvent, render, screen } from '@testing-library/react'; import React from 'react'; import { BrowserRouter } from 'react-router-dom'; -import { SETTING_ITEM } from '../../../constants/LeftSidebar.constants'; +import { + LOGOUT_ITEM, + SETTING_ITEM, +} from '../../../constants/LeftSidebar.constants'; import LeftSidebarItem from './LeftSidebarItem.component'; +const mockOnClick = jest.fn(); + describe('LeftSidebar Items', () => { - it('renders sidebar items data', () => { + it('should renders sidebar items data', () => { render( ); - const item = screen.getByTestId('app-bar-item-settings'); + expect(screen.getByTestId('app-bar-item-settings')).toBeInTheDocument(); + + expect(screen.getByText('label.setting-plural')).toBeInTheDocument(); + + expect(screen.getByRole('img')).toBeInTheDocument(); + }); + + it('should renders sidebar items with redirect url', () => { + render( + + + + ); + + expect(screen.getByTestId('app-bar-item-settings')).toBeInTheDocument(); + + expect(screen.getByText('label.setting-plural')).toBeInTheDocument(); + + expect(screen.getByRole('link')).toBeInTheDocument(); + + expect(screen.getByRole('img')).toBeInTheDocument(); + }); + + it('should renders sidebar items without redirect url', () => { + render( + + + + ); + + expect(screen.getByTestId('app-bar-item-logout')).toBeInTheDocument(); + + expect(screen.getByText('label.logout')).toBeInTheDocument(); + + expect(screen.queryByRole('link')).not.toBeInTheDocument(); + + expect(screen.getByRole('img')).toBeInTheDocument(); + }); + + it('should fire onClick event if provided', () => { + render( + + + + ); + + const logoutItem = screen.getByTestId('app-bar-item-logout'); + + expect(logoutItem).toBeInTheDocument(); + + fireEvent.click(logoutItem); - expect(item).toBeInTheDocument(); + expect(mockOnClick).toHaveBeenCalled(); }); }); diff --git a/openmetadata-ui/src/main/resources/ui/src/components/MyData/LeftSidebar/left-sidebar.less b/openmetadata-ui/src/main/resources/ui/src/components/MyData/LeftSidebar/left-sidebar.less index 550ebd7c36e2..1d7bc1e5a1cb 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/MyData/LeftSidebar/left-sidebar.less +++ b/openmetadata-ui/src/main/resources/ui/src/components/MyData/LeftSidebar/left-sidebar.less @@ -13,125 +13,264 @@ @import url('../../../styles/variables.less'); .left-sidebar-col { - border: 1px solid @border-color; - border-radius: 0; - border-top: 0; + position: relative; background-color: @white !important; - height: calc(100vh - 64px); + z-index: 1; - .ant-menu-item { - height: auto; - padding: 16px; - } - .ant-menu-submenu-title { - height: auto !important; - padding: 0 !important; - } - .ant-menu-submenu { - height: auto; - } - .ant-menu-vertical { - border: none; - width: 100%; - } - .ant-menu-submenu-arrow { - display: none; + .left-sidebar-container { + position: absolute; + top: 0; + left: 0; + width: 60px; + border-radius: 0; + border: 1px solid @border-color; + border-top: 0; + background: @white; + transition: 0.3s ease-in-out; + overflow: hidden; + + // sub menu dropdown will be closed by default + .ant-menu-sub { + display: none; + } + + .ant-menu-submenu-arrow { + opacity: 0; + transition: 0.3s ease-in-out; + } } - .ant-menu-title-content { + + .brand-logo-container { + height: 64px; display: flex; align-items: center; - flex-direction: column; - padding: 16px 8px; + justify-content: center; + background: rgba(248, 248, 248, 1); } -} -.page-layout-leftpanel { - padding: 0 0 24px 0 !important; - border-right: 1px solid @border-color; - overflow: auto; - height: calc(100vh - 64px); - background-color: @white; - overflow-x: hidden; -} -.left-panel-item { - cursor: pointer; - color: @text-grey-muted; - .ant-menu-submenu-vertical { - .ant-menu-submenu-title { - margin: 0; + // Css apply when sidebar is open + + .sidebar-open { + width: 230px; + + .brand-logo-container { + justify-content: flex-start; } - } - svg { - color: @text-grey-muted; - } - padding: 16px 0; - display: flex; - align-items: center; - flex-direction: column; - .service-beta-tag sup { - font-size: 8px; - } -} + .ant-menu-submenu-arrow { + opacity: 1; + } -.left-panel-item.active, -.left-panel-item:hover { - background-color: @left-nav-item-background; - color: @text-color; + .ant-menu-sub { + display: initial; + } - svg { - color: @primary-color; - } -} + .ant-menu-hidden { + display: none; + } -.govern-menu { - width: 100px !important; - .ant-menu-item { - height: auto !important; - margin: 0; - } - .ant-menu-item:hover, - .ant-menu-item-selected { - background-color: @left-nav-item-background; - color: @text-color; - svg { - color: @primary-color; + .ant-menu-submenu-open { + .ant-menu-submenu-title { + background: rgba(9, 80, 197, 0.04); + } } - .left-panel-label { - color: @text-color; + + .left-sidebar-menu.ant-menu { + .ant-menu-item { + .ant-menu-item-icon { + background: rgba(248, 248, 248, 1); + } + + .left-panel-item { + .left-panel-label { + opacity: 1; + } + } + } + + .ant-menu-submenu { + .ant-menu-submenu-title { + .left-panel-item { + .left-panel-label { + opacity: 1; + } + } + } + + .ant-menu-item-icon { + background: rgba(248, 248, 248, 1); + } + } } } - .ant-menu-vertical { - min-width: 58px !important; - width: 58px; - margin-top: 3px; - margin-left: 4px; + + .ant-menu-inline, + .ant-menu-vertical, + .ant-menu-vertical-left { + border: none; + } + + .left-sidebar-menu.ant-menu { .ant-menu-item { - margin: 0; + padding: 8px 0 8px 13px !important; + height: auto; + margin: 4px auto; + transition: 0.3s ease-in-out; + overflow: visible; + + &:after { + border: none; + } + + &:hover { + background: rgba(9, 80, 197, 0.04); + color: @text-color; + + .ant-menu-item-icon { + background: transparent; + } + } + + .left-panel-item { + .service-beta-tag { + position: absolute; + top: -4px; + right: 20px; + sup { + font-size: 8px; + background: @primary-color-hover; + border: 1px solid @primary-color; + color: @primary-color; + } + } + + .anticon { + svg { + font-size: 30px; + fill: transparent; + } + } + + .left-panel-label { + color: @text-grey-muted; + font-weight: 500; + opacity: 0; + } + } + } + + .ant-menu-submenu { + padding: 2px 0; + height: auto; + + .ant-menu-submenu-title { + padding: 8px 0 8px 13px !important; + margin: auto; + height: auto; + + .left-panel-item { + position: relative; + .anticon { + svg { + font-size: 30px; + fill: transparent; + } + } + + .left-panel-label { + font-weight: 500; + color: @text-grey-muted; + opacity: 0; + } + } + } + + .ant-menu-item { + padding: 8px 0 8px 30px !important; + height: auto; + } + + .ant-menu-sub.ant-menu-inline { + background: transparent; + + .ant-menu-item { + padding: 4px 0 4px 30px !important; + height: auto; + + .left-panel-item { + .anticon { + svg { + font-size: 22px; + fill: transparent; + } + } + } + } + } } - .ant-menu-item:not(:last-child) { - margin: 0; + .ant-menu-submenu-selected { + .ant-menu-submenu-title { + background-color: @left-nav-item-background; + + .left-panel-item { + .left-panel-label { + color: @text-color; + } + .anticon { + svg { + color: @primary-color; + } + } + } + } + + .ant-menu-sub.ant-menu-inline { + background: transparent; + } + } + + &:not(.ant-menu-horizontal) .ant-menu-item-selected, + .ant-menu-item:active, + .ant-menu-submenu-title:active, + .ant-menu-item:hover { + background-color: @left-nav-item-background; + color: @text-color; + + .left-panel-item { + .left-panel-label { + color: @text-color; + } + } + + .anticon { + svg { + color: @primary-color !important; + } + } + } + + .ant-menu-submenu:hover + > .ant-menu-submenu-title + > .ant-menu-submenu-expand-icon, + .ant-menu-submenu:hover + > .ant-menu-submenu-title + > .ant-menu-submenu-arrow { + color: initial; } } } -.left-panel-label.ant-typography { - font-size: 12px; - color: @white; - font-weight: 500; - padding: 0 20px; - line-height: 26px; +.left-panel-item.active, +.left-panel-item:hover { text-decoration: none; } -.confirm-btn { - width: 130px; -} - -.left-panel-tooltip { - .ant-tooltip-inner { - padding: 0; - min-height: auto; - } +.page-layout-leftpanel { + padding: 0 0 24px 0 !important; + border-right: 1px solid @border-color; + overflow: auto; + height: calc(100vh - 64px); + background-color: @white; + overflow-x: hidden; } diff --git a/openmetadata-ui/src/main/resources/ui/src/components/NavBar/NavBar.tsx b/openmetadata-ui/src/main/resources/ui/src/components/NavBar/NavBar.tsx index 5a3b891ec789..fff3d1d7412e 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/NavBar/NavBar.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/NavBar/NavBar.tsx @@ -34,7 +34,7 @@ import React, { useState, } from 'react'; import { useTranslation } from 'react-i18next'; -import { Link, useHistory } from 'react-router-dom'; +import { useHistory } from 'react-router-dom'; import { ReactComponent as DropDownIcon } from '../../assets/svg/DropDown.svg'; import { ReactComponent as IconBell } from '../../assets/svg/ic-alert-bell.svg'; import { ReactComponent as DomainIcon } from '../../assets/svg/ic-domain.svg'; @@ -69,7 +69,6 @@ import SVGIcons, { Icons } from '../../utils/SvgUtils'; import { ActivityFeedTabs } from '../ActivityFeed/ActivityFeedTab/ActivityFeedTab.interface'; import SearchOptions from '../AppBar/SearchOptions'; import Suggestions from '../AppBar/Suggestions'; -import BrandImage from '../common/BrandImage/BrandImage'; import CmdKIcon from '../common/CmdKIcon/CmdKIcon.component'; import { useDomainProvider } from '../Domain/DomainProvider/DomainProvider'; import { useGlobalSearchProvider } from '../GlobalSearchProvider/GlobalSearchProvider'; @@ -330,16 +329,6 @@ const NavBar = ({ return ( <>
- - -
{ data-testid={`${condition}-select`} mode="multiple" options={ - func.paramAdditionalContext?.data?.map((d) => ({ + func.paramAdditionalContext?.data?.map((d: string) => ({ label: startCase(d), value: d, })) ?? [] diff --git a/openmetadata-ui/src/main/resources/ui/src/utils/LeftSidebarClassBase.ts b/openmetadata-ui/src/main/resources/ui/src/utils/LeftSidebarClassBase.ts index ee40da29c95a..96f6c7dd9951 100644 --- a/openmetadata-ui/src/main/resources/ui/src/utils/LeftSidebarClassBase.ts +++ b/openmetadata-ui/src/main/resources/ui/src/utils/LeftSidebarClassBase.ts @@ -10,17 +10,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { FC } from 'react'; import { SIDEBAR_LIST } from '../constants/LeftSidebar.constants'; class LeftSidebarClassBase { - /** - * getSidebarElements - */ - public getSidebarElements(): FC | null { - return null; - } - /** * getSidebarItems */