diff --git a/openmetadata-ui/src/main/resources/ui/cypress/common/CustomizeLandingPageUtils.ts b/openmetadata-ui/src/main/resources/ui/cypress/common/CustomizeLandingPageUtils.ts deleted file mode 100644 index c7c270e9140..00000000000 --- a/openmetadata-ui/src/main/resources/ui/cypress/common/CustomizeLandingPageUtils.ts +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright 2024 Collate. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { GlobalSettingOptions } from '../constants/settings.constant'; -import { - interceptURL, - toastNotification, - verifyResponseStatusCode, -} from './common'; - -export const removeAndCheckWidget = ({ widgetTestId, widgetKey }) => { - // Click on remove widget button - cy.get( - `[data-testid="${widgetTestId}"] [data-testid="remove-widget-button"]` - ).click({ waitForAnimations: true }); - - cy.get(`[data-testid="${widgetTestId}"]`).should('not.exist'); - - // Check if empty widget placeholder is displayed in place of removed widget - cy.get( - `[data-testid*="${widgetKey}"][data-testid$="EmptyWidgetPlaceholder"]` - ).should('exist'); - - // Remove empty widget placeholder - cy.get( - `[data-testid*="${widgetKey}"][data-testid$="EmptyWidgetPlaceholder"] [data-testid="remove-widget-button"]` - ).click({ waitForAnimations: true }); - cy.get( - `[data-testid*="${widgetKey}"][data-testid$="EmptyWidgetPlaceholder"]` - ).should('not.exist'); -}; - -export const navigateToCustomizeLandingPage = ({ - personaName, - customPageDataResponse, -}) => { - interceptURL('GET', '/api/v1/personas*', 'getPersonas'); - - cy.settingClick(GlobalSettingOptions.CUSTOMIZE_LANDING_PAGE); - - verifyResponseStatusCode('@getPersonas', 200); - - interceptURL( - 'GET', - `/api/v1/docStore/name/persona.${personaName}.Page.LandingPage`, - 'getCustomPageData' - ); - interceptURL( - 'GET', - '/api/v1/search/query?q=*%20AND%20followers:**', - 'getFollowersData' - ); - - cy.get( - `[data-testid="persona-details-card-${personaName}"] [data-testid="customize-page-button"]` - ).click(); - - verifyResponseStatusCode('@getCustomPageData', customPageDataResponse); - verifyResponseStatusCode('@getFollowersData', 200); -}; - -export const saveLayout = () => { - // Save layout - interceptURL('PATCH', `/api/v1/docStore/*`, 'getMyData'); - - cy.get('[data-testid="save-button"]').click(); - - verifyResponseStatusCode('@getMyData', 200); - - toastNotification('Page layout updated successfully.'); -}; - -export const navigateToLandingPage = () => { - interceptURL('GET', `/api/v1/feed*`, 'getFeedsData'); - interceptURL( - 'GET', - `/api/v1/analytics/dataInsights/system/charts/name/total_data_assets/data?*`, - 'getDataInsightReport' - ); - - cy.get('#openmetadata_logo').click(); - - verifyResponseStatusCode('@getFeedsData', 200); - verifyResponseStatusCode('@getDataInsightReport', 200); -}; - -export const openAddWidgetModal = () => { - interceptURL( - 'GET', - `/api/v1/docStore?fqnPrefix=KnowledgePanel&limit=25`, - 'getWidgetsList' - ); - - cy.get( - '[data-testid="ExtraWidget.EmptyWidgetPlaceholder"] [data-testid="add-widget-button"]' - ).click(); - - verifyResponseStatusCode('@getWidgetsList', 200); -}; - -export const checkAllWidgets = (checkEmptyWidgetPlaceholder = false) => { - cy.get('[data-testid="activity-feed-widget"]').should('exist'); - cy.get('[data-testid="following-widget"]').should('exist'); - cy.get('[data-testid="recently-viewed-widget"]').should('exist'); - cy.get('[data-testid="my-data-widget"]').should('exist'); - cy.get('[data-testid="kpi-widget"]').should('exist'); - cy.get('[data-testid="total-assets-widget"]').should('exist'); - if (checkEmptyWidgetPlaceholder) { - cy.get('[data-testid="ExtraWidget.EmptyWidgetPlaceholder"]').should( - 'exist' - ); - } -}; diff --git a/openmetadata-ui/src/main/resources/ui/cypress/constants/EntityConstant.ts b/openmetadata-ui/src/main/resources/ui/cypress/constants/EntityConstant.ts index 4807a2b0a22..118c387cb76 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/constants/EntityConstant.ts +++ b/openmetadata-ui/src/main/resources/ui/cypress/constants/EntityConstant.ts @@ -446,12 +446,6 @@ export const USER_DETAILS = { password: 'User@OMD123', }; -export const PERSONA_DETAILS = { - name: `persona-${uuid()}`, - displayName: `persona ${uuid()}`, - description: `Persona description.`, -}; - export const DOMAIN_CREATION_DETAILS = { name: `domain-name-${uuid()}`, description: `Description for`, diff --git a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Flow/CustomizeLandingPage.spec.ts b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Flow/CustomizeLandingPage.spec.ts deleted file mode 100644 index ff3f2aa0b39..00000000000 --- a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Flow/CustomizeLandingPage.spec.ts +++ /dev/null @@ -1,238 +0,0 @@ -/* - * Copyright 2024 Collate. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { compare } from 'fast-json-patch'; -import { interceptURL, toastNotification } from '../../common/common'; -import { - checkAllWidgets, - navigateToCustomizeLandingPage, - navigateToLandingPage, - openAddWidgetModal, - removeAndCheckWidget, - saveLayout, -} from '../../common/CustomizeLandingPageUtils'; -import { getToken } from '../../common/Utils/LocalStorage'; -import { PERSONA_DETAILS } from '../../constants/EntityConstant'; - -describe('Customize Landing Page Flow', { tags: 'Settings' }, () => { - const testData = {}; - before(() => { - cy.login(); - cy.getAllLocalStorage().then((data) => { - const token = getToken(data); - - // Fetch logged in user details to get user id - cy.request({ - method: 'GET', - url: `/api/v1/users/loggedInUser`, - headers: { Authorization: `Bearer ${token}` }, - }).then((userResponse) => { - // Create a persona - cy.request({ - method: 'POST', - url: `/api/v1/personas`, - headers: { Authorization: `Bearer ${token}` }, - body: { ...PERSONA_DETAILS, users: [userResponse.body.id] }, - }).then((personaResponse) => { - testData.user = userResponse.body; - testData.persona = personaResponse.body; - const { - name, - id, - description, - displayName, - fullyQualifiedName, - href, - } = personaResponse.body; - - // Set newly created persona as default persona for the logged in user - const patchData = compare(userResponse.body, { - ...userResponse.body, - defaultPersona: { - name, - id, - description, - displayName, - fullyQualifiedName, - href, - type: 'persona', - }, - }); - - cy.request({ - method: 'PATCH', - url: `/api/v1/users/${testData.user.id}`, - headers: { - Authorization: `Bearer ${token}`, - 'Content-Type': 'application/json-patch+json', - }, - body: patchData, - }); - }); - }); - }); - }); - - after(() => { - cy.login(); - cy.getAllLocalStorage().then((data) => { - const token = getToken(data); - - // Delete created user - cy.request({ - method: 'DELETE', - url: `/api/v1/personas/${testData.persona.id}`, - headers: { Authorization: `Bearer ${token}` }, - }); - - // Delete created landing page config doc - cy.request({ - method: 'DELETE', - url: `/api/v1/docStore/${testData.docStoreData.id}`, - headers: { Authorization: `Bearer ${token}` }, - }); - }); - }); - - beforeEach(() => { - cy.login(); - }); - - it('Creation of custom landing page config and widget removal should work properly', () => { - navigateToCustomizeLandingPage({ - personaName: PERSONA_DETAILS.name, - customPageDataResponse: 404, - }); - - checkAllWidgets(true); - - // Editing the layout - removeAndCheckWidget({ - widgetTestId: 'activity-feed-widget', - widgetKey: 'KnowledgePanel.ActivityFeed', - }); - removeAndCheckWidget({ - widgetTestId: 'following-widget', - widgetKey: 'KnowledgePanel.Following', - }); - removeAndCheckWidget({ - widgetTestId: 'kpi-widget', - widgetKey: 'KnowledgePanel.KPI', - }); - - // Save layout - interceptURL('POST', `/api/v1/docStore`, 'getMyData'); - - cy.get('[data-testid="save-button"]').click(); - - cy.wait('@getMyData').then((interception) => { - testData.docStoreData = interception.response.body; - - expect(interception.response.statusCode).equal(201); - }); - - toastNotification('Page layout created successfully.'); - - cy.goToHomePage(); - - // Check if removed widgets are not present on landing page - cy.get(`[data-testid="activity-feed-widget"]`).should('not.exist'); - cy.get(`[data-testid="following-widget"]`).should('not.exist'); - cy.get(`[data-testid="kpi-widget"]`).should('not.exist'); - }); - - it('Adding new widget should work properly', () => { - navigateToCustomizeLandingPage({ - personaName: PERSONA_DETAILS.name, - customPageDataResponse: 200, - }); - - // Check if removed widgets are not present on customize page - cy.get('[data-testid="activity-feed-widget"]').should('not.exist'); - cy.get('[data-testid="following-widget"]').should('not.exist'); - cy.get('[data-testid="kpi-widget"]').should('not.exist'); - - // Check if other widgets are present - cy.get('[data-testid="recently-viewed-widget"]').should('exist'); - cy.get('[data-testid="my-data-widget"]').should('exist'); - cy.get('[data-testid="total-assets-widget"]').should('exist'); - cy.get('[data-testid="ExtraWidget.EmptyWidgetPlaceholder"]').should( - 'exist' - ); - - openAddWidgetModal(); - - // Check if 'check' icon is present for existing widgets - cy.get('[data-testid="MyData-check-icon"]').should('exist'); - cy.get('[data-testid="RecentlyViewed-check-icon"]').should('exist'); - cy.get('[data-testid="TotalAssets-check-icon"]').should('exist'); - - // Check if 'check' icon is not present for removed widgets - cy.get('[data-testid="ActivityFeed-check-icon"]').should('not.exist'); - cy.get('[data-testid="Following-check-icon"]').should('not.exist'); - cy.get('[data-testid="KPI-check-icon"]').should('not.exist'); - - // Add Following widget - cy.get('[data-testid="Following-widget-tab-label"]').click(); - cy.get( - '[aria-labelledby$="KnowledgePanel.Following"] [data-testid="add-widget-button"]' - ).click(); - cy.get('[data-testid="following-widget"]').should('exist'); - - // Check if check icons are present in tab labels for newly added widgets - openAddWidgetModal(); - cy.get('[data-testid="Following-check-icon"]').should('exist'); - cy.get('[data-testid="add-widget-modal"] [aria-label="Close"]').click(); - - saveLayout(); - - navigateToLandingPage(); - - cy.get(`[data-testid="activity-feed-widget"]`).should('not.exist'); - cy.get(`[data-testid="kpi-widget"]`).should('not.exist'); - - // Check if newly added widgets are present on landing page - cy.get(`[data-testid="following-widget"]`).should('exist'); - }); - - it('Resetting the layout flow should work properly', () => { - // Check if removed widgets are not present on landing page - cy.get(`[data-testid="activity-feed-widget"]`).should('not.exist'); - cy.get(`[data-testid="kpi-widget"]`).should('not.exist'); - - navigateToCustomizeLandingPage({ - personaName: PERSONA_DETAILS.name, - customPageDataResponse: 200, - }); - - // Check if removed widgets are not present on customize page - cy.get(`[data-testid="activity-feed-widget"]`).should('not.exist'); - cy.get(`[data-testid="kpi-widget"]`).should('not.exist'); - - cy.get(`[data-testid="reset-button"]`).click(); - - cy.get(`[data-testid="reset-layout-modal"] .ant-modal-footer`) - .contains('Yes') - .click(); - - toastNotification('Page layout updated successfully.'); - - // Check if all widgets are present after resetting the layout - checkAllWidgets(true); - - // Check if all widgets are present on landing page - navigateToLandingPage(); - - checkAllWidgets(); - }); -}); diff --git a/openmetadata-ui/src/main/resources/ui/playwright/e2e/Flow/CustomizeLandingPage.spec.ts b/openmetadata-ui/src/main/resources/ui/playwright/e2e/Flow/CustomizeLandingPage.spec.ts index 7a9ee664917..b0cba878881 100644 --- a/openmetadata-ui/src/main/resources/ui/playwright/e2e/Flow/CustomizeLandingPage.spec.ts +++ b/openmetadata-ui/src/main/resources/ui/playwright/e2e/Flow/CustomizeLandingPage.spec.ts @@ -14,11 +14,13 @@ import { expect, Page, test as base } from '@playwright/test'; import { PersonaClass } from '../../support/persona/PersonaClass'; import { UserClass } from '../../support/user/UserClass'; import { performAdminLogin } from '../../utils/admin'; -import { redirectToHomePage, toastNotification } from '../../utils/common'; +import { redirectToHomePage } from '../../utils/common'; import { checkAllDefaultWidgets, navigateToCustomizeLandingPage, + openAddCustomizeWidgetModal, removeAndCheckWidget, + saveCustomizeLayoutPage, setUserDefaultPersona, } from '../../utils/customizeLandingPage'; @@ -59,44 +61,199 @@ test.describe('Customize Landing Page Flow', () => { await checkAllDefaultWidgets(adminPage); }); - test('Remove and check widget', async ({ adminPage }) => { + test('Add,Remove and Reset widget should work properly', async ({ + adminPage, + }) => { + test.slow(true); + await redirectToHomePage(adminPage); await setUserDefaultPersona(adminPage, persona.responseData.displayName); - await navigateToCustomizeLandingPage(adminPage, { - personaName: persona.responseData.name, - customPageDataResponse: 404, + + await test.step('Remove widget', async () => { + await navigateToCustomizeLandingPage(adminPage, { + personaName: persona.responseData.name, + customPageDataResponse: 404, + }); + + await removeAndCheckWidget(adminPage, { + widgetTestId: 'activity-feed-widget', + widgetKey: 'KnowledgePanel.ActivityFeed', + }); + await removeAndCheckWidget(adminPage, { + widgetTestId: 'following-widget', + widgetKey: 'KnowledgePanel.Following', + }); + await removeAndCheckWidget(adminPage, { + widgetTestId: 'kpi-widget', + widgetKey: 'KnowledgePanel.KPI', + }); + + await saveCustomizeLayoutPage(adminPage, true); + + await redirectToHomePage(adminPage); + + // Check if removed widgets are not present on landing adminPage + await expect( + adminPage.locator('[data-testid="activity-feed-widget"]') + ).not.toBeVisible(); + await expect( + adminPage.locator('[data-testid="following-widget"]') + ).not.toBeVisible(); + await expect( + adminPage.locator('[data-testid="kpi-widget"]') + ).not.toBeVisible(); }); - await removeAndCheckWidget(adminPage, { - widgetTestId: 'activity-feed-widget', - widgetKey: 'KnowledgePanel.ActivityFeed', - }); - await removeAndCheckWidget(adminPage, { - widgetTestId: 'following-widget', - widgetKey: 'KnowledgePanel.Following', - }); - await removeAndCheckWidget(adminPage, { - widgetTestId: 'kpi-widget', - widgetKey: 'KnowledgePanel.KPI', + await test.step('Add widget', async () => { + await navigateToCustomizeLandingPage(adminPage, { + personaName: persona.responseData.name, + customPageDataResponse: 200, + }); + + // Check if removed widgets are not present on customize page + await expect( + adminPage.locator('[data-testid="activity-feed-widget"]') + ).not.toBeVisible(); + await expect( + adminPage.locator('[data-testid="following-widget"]') + ).not.toBeVisible(); + await expect( + adminPage.locator('[data-testid="kpi-widget"]') + ).not.toBeVisible(); + + // Check if other widgets are present + await expect( + adminPage.locator('[data-testid="recently-viewed-widget"]') + ).toBeVisible(); + await expect( + adminPage.locator('[data-testid="my-data-widget"]') + ).toBeVisible(); + await expect( + adminPage.locator('[data-testid="total-assets-widget"]') + ).toBeVisible(); + await expect( + adminPage.locator('[data-testid="ExtraWidget.EmptyWidgetPlaceholder"]') + ).toBeVisible(); + + await openAddCustomizeWidgetModal(adminPage); + + // Check if 'check' icon is present for existing widgets + await expect( + adminPage.locator('[data-testid="MyData-check-icon"]') + ).toBeVisible(); + await expect( + adminPage.locator('[data-testid="RecentlyViewed-check-icon"]') + ).toBeVisible(); + await expect( + adminPage.locator('[data-testid="TotalAssets-check-icon"]') + ).toBeVisible(); + + // Check if 'check' icon is not present for removed widgets + await expect( + adminPage.locator('[data-testid="ActivityFeed-check-icon"]') + ).not.toBeVisible(); + await expect( + adminPage.locator('[data-testid="Following-check-icon"]') + ).not.toBeVisible(); + await expect( + adminPage.locator('[data-testid="KPI-check-icon"]') + ).not.toBeVisible(); + + // Add Following widget + await adminPage + .locator('[data-testid="Following-widget-tab-label"]') + .click(); + await adminPage + .locator( + '[aria-labelledby$="KnowledgePanel.Following"] [data-testid="add-widget-button"]' + ) + .click(); + + await expect( + adminPage.locator('[data-testid="following-widget"]') + ).toBeVisible(); + + // Check if check icons are present in tab labels for newly added widgets + await openAddCustomizeWidgetModal(adminPage); + + // Check if 'check' icon is present for the Following widget + await expect( + adminPage.locator('[data-testid="Following-check-icon"]') + ).toBeVisible(); + + // Close the add widget modal + await adminPage + .locator('[data-testid="add-widget-modal"] [aria-label="Close"]') + .click(); + + // Save the updated layout + await saveCustomizeLayoutPage(adminPage); + + // Navigate to the landing page + await redirectToHomePage(adminPage); + + // Check if removed widgets are not present on the landing page + await expect( + adminPage.locator('[data-testid="activity-feed-widget"]') + ).not.toBeVisible(); + await expect( + adminPage.locator('[data-testid="kpi-widget"]') + ).not.toBeVisible(); + + // Check if newly added widgets are present on the landing page + await expect( + adminPage.locator('[data-testid="following-widget"]') + ).toBeVisible(); }); - const saveResponse = adminPage.waitForResponse('/api/v1/docStore'); - await adminPage.click('[data-testid="save-button"]'); - await saveResponse; + await test.step( + 'Resetting the layout flow should work properly', + async () => { + // Check if removed widgets are not present on landing page + await expect( + adminPage.locator('[data-testid="activity-feed-widget"]') + ).not.toBeVisible(); + await expect( + adminPage.locator('[data-testid="kpi-widget"]') + ).not.toBeVisible(); - await toastNotification(adminPage, 'Page layout created successfully.'); - await redirectToHomePage(adminPage); + await navigateToCustomizeLandingPage(adminPage, { + personaName: persona.responseData.name, + customPageDataResponse: 200, + }); - // Check if removed widgets are not present on landing adminPage - await expect( - adminPage.locator('[data-testid="activity-feed-widget"]') - ).not.toBeVisible(); - await expect( - adminPage.locator('[data-testid="following-widget"]') - ).not.toBeVisible(); - await expect( - adminPage.locator('[data-testid="kpi-widget"]') - ).not.toBeVisible(); + // Check if removed widgets are not present on customize page + await expect( + adminPage.locator('[data-testid="activity-feed-widget"]') + ).not.toBeVisible(); + await expect( + adminPage.locator('[data-testid="kpi-widget"]') + ).not.toBeVisible(); + + await adminPage.locator('[data-testid="reset-button"]').click(); + + // Confirm reset in modal + await adminPage + .locator('[data-testid="reset-layout-modal"] .ant-modal-footer') + .locator('text=Yes') + .click(); + + // Verify the toast notification + const toastNotification = adminPage.locator('.Toastify__toast-body'); + + await expect(toastNotification).toContainText( + 'Page layout updated successfully.' + ); + + // Check if all widgets are present after resetting the layout + await checkAllDefaultWidgets(adminPage, true); + + // Check if all widgets are present on landing page + await redirectToHomePage(adminPage); + + await checkAllDefaultWidgets(adminPage); + } + ); }); test('Remove and add the widget in the same placeholder', async ({ @@ -175,10 +332,6 @@ test.describe('Customize Landing Page Flow', () => { // Check if the KPI widget is added in the same placeholder,by their transform property or placement. expect(kpiElementStyle.transform).toEqual(followingElementStyle.transform); - const saveResponse = adminPage.waitForResponse('/api/v1/docStore'); - await adminPage.click('[data-testid="save-button"]'); - await saveResponse; - - await toastNotification(adminPage, 'Page layout created successfully.'); + await saveCustomizeLayoutPage(adminPage, true); }); }); diff --git a/openmetadata-ui/src/main/resources/ui/playwright/utils/customizeLandingPage.ts b/openmetadata-ui/src/main/resources/ui/playwright/utils/customizeLandingPage.ts index f9cbeb05656..a73082ed969 100644 --- a/openmetadata-ui/src/main/resources/ui/playwright/utils/customizeLandingPage.ts +++ b/openmetadata-ui/src/main/resources/ui/playwright/utils/customizeLandingPage.ts @@ -12,7 +12,7 @@ */ import { expect, Page } from '@playwright/test'; import { GlobalSettingOptions } from '../constant/settings'; -import { visitOwnProfilePage } from './common'; +import { toastNotification, visitOwnProfilePage } from './common'; import { settingClick } from './sidebar'; export const navigateToCustomizeLandingPage = async ( @@ -117,3 +117,32 @@ export const setUserDefaultPersona = async ( page.locator('[data-testid="user-profile-details"]') ).toContainText(personaName); }; + +export const openAddCustomizeWidgetModal = async (page: Page) => { + const fetchResponse = page.waitForResponse( + '/api/v1/docStore?fqnPrefix=KnowledgePanel*' + ); + await page + .locator( + '[data-testid="ExtraWidget.EmptyWidgetPlaceholder"] [data-testid="add-widget-button"]' + ) + .click(); + + await fetchResponse; +}; + +export const saveCustomizeLayoutPage = async ( + page: Page, + isCreated?: boolean +) => { + const saveResponse = page.waitForResponse( + isCreated ? '/api/v1/docStore' : '/api/v1/docStore/*' + ); + await page.locator('[data-testid="save-button"]').click(); + await saveResponse; + + await toastNotification( + page, + `Page layout ${isCreated ? 'created' : 'updated'} successfully.` + ); +};