diff --git a/openmetadata-ui/src/main/resources/ui/playwright/constant/explore.ts b/openmetadata-ui/src/main/resources/ui/playwright/constant/explore.ts new file mode 100644 index 000000000000..f971a6eacc94 --- /dev/null +++ b/openmetadata-ui/src/main/resources/ui/playwright/constant/explore.ts @@ -0,0 +1,30 @@ +/* + * 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. + */ +export const EXPECTED_BUCKETS = [ + 'table', + 'glossaryTerm', + 'databaseSchema', + 'chart', + 'storedProcedure', + 'database', + 'pipeline', + 'dashboard', + 'container', + 'tag', + 'dashboardDataModel', + 'apiEndpoint', + 'topic', + 'apiCollection', + 'searchIndex', + 'mlmodel', +]; diff --git a/openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/ExploreTree.spec.ts b/openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/ExploreTree.spec.ts index 346131401181..0fe6fc1b7dfa 100644 --- a/openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/ExploreTree.spec.ts +++ b/openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/ExploreTree.spec.ts @@ -13,10 +13,22 @@ import test, { expect } from '@playwright/test'; import { get } from 'lodash'; import { SidebarItem } from '../../constant/sidebar'; +import { ApiEndpointClass } from '../../support/entity/ApiEndpointClass'; +import { ContainerClass } from '../../support/entity/ContainerClass'; +import { DashboardClass } from '../../support/entity/DashboardClass'; +import { DashboardDataModelClass } from '../../support/entity/DashboardDataModelClass'; import { EntityTypeEndpoint } from '../../support/entity/Entity.interface'; +import { MlModelClass } from '../../support/entity/MlModelClass'; +import { PipelineClass } from '../../support/entity/PipelineClass'; +import { SearchIndexClass } from '../../support/entity/SearchIndexClass'; +import { StoredProcedureClass } from '../../support/entity/StoredProcedureClass'; import { TableClass } from '../../support/entity/TableClass'; +import { TopicClass } from '../../support/entity/TopicClass'; +import { Glossary } from '../../support/glossary/Glossary'; +import { GlossaryTerm } from '../../support/glossary/GlossaryTerm'; import { getApiContext, redirectToHomePage } from '../../utils/common'; import { updateDisplayNameForEntity } from '../../utils/entity'; +import { validateBucketsForIndex } from '../../utils/explore'; import { sidebarClick } from '../../utils/sidebar'; // use the admin user to login @@ -192,6 +204,53 @@ test.describe('Explore Tree scenarios ', () => { }); test.describe('Explore page', () => { + const table = new TableClass(); + const glossary = new Glossary(); + const glossaryTerm = new GlossaryTerm(glossary); + const dashboard = new DashboardClass(); + const storedProcedure = new StoredProcedureClass(); + const pipeline = new PipelineClass(); + const container = new ContainerClass(); + const apiEndpoint = new ApiEndpointClass(); + const topic = new TopicClass(); + const searchIndex = new SearchIndexClass(); + const dashboardDataModel = new DashboardDataModelClass(); + const mlModel = new MlModelClass(); + + test.beforeEach('Setup pre-requisits', async ({ page }) => { + const { apiContext, afterAction } = await getApiContext(page); + await table.create(apiContext); + await glossary.create(apiContext); + await glossaryTerm.create(apiContext); + await dashboard.create(apiContext); + await storedProcedure.create(apiContext); + await pipeline.create(apiContext); + await container.create(apiContext); + await apiEndpoint.create(apiContext); + await topic.create(apiContext); + await searchIndex.create(apiContext); + await dashboardDataModel.create(apiContext); + await mlModel.create(apiContext); + await afterAction(); + }); + + test.afterEach('Cleanup', async ({ page }) => { + const { apiContext, afterAction } = await getApiContext(page); + await table.delete(apiContext); + await glossary.delete(apiContext); + await glossaryTerm.delete(apiContext); + await dashboard.delete(apiContext); + await storedProcedure.delete(apiContext); + await pipeline.delete(apiContext); + await container.delete(apiContext); + await apiEndpoint.delete(apiContext); + await topic.delete(apiContext); + await searchIndex.delete(apiContext); + await dashboardDataModel.delete(apiContext); + await mlModel.delete(apiContext); + await afterAction(); + }); + test('Check the listing of tags', async ({ page }) => { await page .locator('div') @@ -214,4 +273,14 @@ test.describe('Explore page', () => { expect(jsonResponse.hits.hits.length).toBeGreaterThan(0); }); + + test('Check listing of entities when index is dataAsset', async ({ + page, + }) => { + await validateBucketsForIndex(page, 'dataAsset'); + }); + + test('Check listing of entities when index is all', async ({ page }) => { + await validateBucketsForIndex(page, 'all'); + }); }); diff --git a/openmetadata-ui/src/main/resources/ui/playwright/utils/explore.ts b/openmetadata-ui/src/main/resources/ui/playwright/utils/explore.ts index fbe65243af9d..f3bb5b71ac0b 100644 --- a/openmetadata-ui/src/main/resources/ui/playwright/utils/explore.ts +++ b/openmetadata-ui/src/main/resources/ui/playwright/utils/explore.ts @@ -12,6 +12,13 @@ */ import { expect } from '@playwright/test'; import { Page } from 'playwright'; +import { EXPECTED_BUCKETS } from '../constant/explore'; +import { getApiContext } from './common'; + +export interface Bucket { + key: string; + doc_count: number; +} export const searchAndClickOnOption = async ( page: Page, @@ -116,3 +123,28 @@ export const selectDataAssetFilter = async ( await page.getByTestId(`${filterValue}-checkbox`).check(); await page.getByTestId('update-btn').click(); }; + +export const validateBucketsForIndex = async (page: Page, index: string) => { + const { apiContext } = await getApiContext(page); + + const response = await apiContext + .get( + `/api/v1/search/query?q=&index=${index}&from=0&size=10&deleted=false&query_filter=%7B%22query%22:%7B%22bool%22:%7B%7D%7D%7D&sort_field=totalVotes&sort_order=desc` + ) + .then((res) => res.json()); + + const buckets = response.aggregations?.['sterms#entityType']?.buckets ?? []; + + EXPECTED_BUCKETS.forEach((expectedKey) => { + const bucket = buckets.find((b: Bucket) => b.key === expectedKey); + + // Expect the bucket to exist + expect(bucket, `Bucket with key "${expectedKey}" is missing`).toBeDefined(); + + // Expect the bucket's doc_count to be greater than 0 + expect( + bucket?.doc_count, + `Bucket "${expectedKey}" has doc_count <= 0` + ).toBeGreaterThan(0); + }); +};