-
Notifications
You must be signed in to change notification settings - Fork 1.7k
test: enhance lineage spec to cover all the missing cases #26796
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
29 commits
Select commit
Hold shift + click to select a range
086eb06
test: enhance lineage spec to cover all the missing cases
chirag-madlani 8854c41
fix searchIndex mapping
chirag-madlani e4a97d1
fix tests
chirag-madlani 6940be5
added filter spec
chirag-madlani 724047f
fix filter issues
chirag-madlani 452ec3d
fix lineageSearchSelect
chirag-madlani 2f3885c
update database service filter tests
chirag-madlani 1072026
iterate over all the entity for service filter
chirag-madlani 0ca985b
update impact analysis fixes
chirag-madlani f1bc45d
update tests management
chirag-madlani 25a9a86
Merge branch 'fix-column-filtering' into lineage-e2e-tests
chirag-madlani d3c345c
add missing test case
chirag-madlani 0e82463
fix tests
chirag-madlani 9fb787d
fix column level lineage tests
chirag-madlani e7f7807
fix apiEndpoint issue
chirag-madlani cc0d57f
improved lineage connection assertion
chirag-madlani de50d4f
fix tests
chirag-madlani 3da4e7e
fix column level linage issues
chirag-madlani 5f4b41b
fix missing import
chirag-madlani 7427ed6
update test import from pages
chirag-madlani c402c44
fix mlModel spell issue
chirag-madlani 8c3e8fe
fix node pagination and right panel spec
chirag-madlani f152805
refactor lineage tests to improve entity creation and visibility checks
chirag-madlani b6de992
Merge branch 'fix-column-filtering' into lineage-e2e-tests
chirag-madlani aac3a54
fix license header
chirag-madlani b48990c
fix build
chirag-madlani 7329f81
fix tests
chirag-madlani 117135d
Merge branch 'fix-column-filtering' into lineage-e2e-tests
chirag-madlani d135767
fix tests
chirag-madlani File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
2,015 changes: 0 additions & 2,015 deletions
2,015
openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/Lineage.spec.ts
This file was deleted.
Oops, something went wrong.
508 changes: 508 additions & 0 deletions
508
openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/Lineage/DataAssetLineage.spec.ts
Large diffs are not rendered by default.
Oops, something went wrong.
255 changes: 255 additions & 0 deletions
255
openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/Lineage/LineageControls.spec.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,255 @@ | ||
| /* | ||
| * Copyright 2026 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 { expect } from '@playwright/test'; | ||
| import { get } from 'lodash'; | ||
| import { SidebarItem } from '../../../constant/sidebar'; | ||
| import { EntityDataClass } from '../../../support/entity/EntityDataClass'; | ||
| import { PipelineClass } from '../../../support/entity/PipelineClass'; | ||
| import { TableClass } from '../../../support/entity/TableClass'; | ||
| import { TopicClass } from '../../../support/entity/TopicClass'; | ||
| import { | ||
| getApiContext, | ||
| getDefaultAdminAPIContext, | ||
| redirectToHomePage, | ||
| } from '../../../utils/common'; | ||
| import { waitForAllLoadersToDisappear } from '../../../utils/entity'; | ||
| import { | ||
| clickLineageNode, | ||
| connectEdgeBetweenNodesViaAPI, | ||
| performZoomOut, | ||
| visitLineageTab, | ||
| } from '../../../utils/lineage'; | ||
| import { sidebarClick } from '../../../utils/sidebar'; | ||
| import { test } from '../../fixtures/pages'; | ||
|
|
||
| const table = new TableClass(); | ||
| const topic = new TopicClass(); | ||
| const pipeline = new PipelineClass(); | ||
|
|
||
| test.beforeAll(async ({ browser }) => { | ||
| const { apiContext, afterAction } = await getDefaultAdminAPIContext(browser); | ||
|
|
||
| await Promise.all([ | ||
| table.create(apiContext), | ||
| topic.create(apiContext), | ||
| pipeline.create(apiContext), | ||
| ]); | ||
|
|
||
| // Patch topic with metadata for filter tests | ||
| await topic.patch({ | ||
| apiContext, | ||
| patchData: [ | ||
| { | ||
| op: 'add', | ||
| path: '/owners/0', | ||
| value: { | ||
| type: 'user', | ||
| id: EntityDataClass.user1.responseData.id, | ||
| }, | ||
| }, | ||
| { | ||
| op: 'add', | ||
| path: '/domains/0', | ||
| value: { | ||
| type: 'domain', | ||
| id: EntityDataClass.domain1.responseData.id, | ||
| }, | ||
| }, | ||
| ], | ||
| }); | ||
|
|
||
| await connectEdgeBetweenNodesViaAPI( | ||
| apiContext, | ||
| { id: table.entityResponseData.id, type: 'table' }, | ||
| { id: topic.entityResponseData.id, type: 'topic' } | ||
| ); | ||
|
|
||
| await afterAction(); | ||
| }); | ||
|
|
||
| test.afterAll(async ({ browser }) => { | ||
| const { apiContext, afterAction } = await getDefaultAdminAPIContext(browser); | ||
| await Promise.all([ | ||
| table.delete(apiContext), | ||
| topic.delete(apiContext), | ||
| pipeline.delete(apiContext), | ||
| ]); | ||
| await afterAction(); | ||
| }); | ||
|
|
||
| test.beforeEach(async ({ page }) => { | ||
| await redirectToHomePage(page); | ||
| }); | ||
|
|
||
| // ==================== | ||
| // Suite 1: Canvas Control Buttons (4 tests) | ||
| // ==================== | ||
| test.describe('Canvas Controls', () => { | ||
| test.beforeEach(async ({ page }) => { | ||
| await table.visitEntityPage(page); | ||
| await visitLineageTab(page); | ||
| await performZoomOut(page); | ||
| }); | ||
|
|
||
| test('Verify zoom in and zoom out controls', async ({ page }) => { | ||
| const zoomInBtn = page.getByTestId('zoom-in'); | ||
| const zoomOutBtn = page.getByTestId('zoom-out'); | ||
|
|
||
| await performZoomOut(page, 5); | ||
|
|
||
| for (let i = 0; i < 3; i++) { | ||
| await zoomInBtn.click(); | ||
| } | ||
|
|
||
| for (let i = 0; i < 3; i++) { | ||
| await zoomOutBtn.click(); | ||
| } | ||
|
|
||
| await expect(zoomInBtn).toBeVisible(); | ||
| await expect(zoomOutBtn).toBeVisible(); | ||
| }); | ||
|
|
||
| test('Verify fit view options menu', async ({ page }) => { | ||
| await page.getByTestId('fit-screen').click(); | ||
| await expect(page.locator('#lineage-view-options-menu')).toBeVisible(); | ||
|
|
||
| await page.getByRole('menuitem', { name: 'Fit to screen' }).click(); | ||
|
|
||
| const tableFqn = get(table, 'entityResponseData.fullyQualifiedName', ''); | ||
| await clickLineageNode(page, tableFqn); | ||
|
|
||
| await page.getByTestId('drawer-close-icon').click(); | ||
|
|
||
| await page.getByTestId('fit-screen').click(); | ||
| await page.getByRole('menuitem', { name: 'Refocused to selected' }).click(); | ||
|
|
||
| await page.getByTestId('fit-screen').click(); | ||
| await page.getByRole('menuitem', { name: 'Rearrange Nodes' }).click(); | ||
|
|
||
| await page.getByTestId('fit-screen').click(); | ||
| await page.getByRole('menuitem', { name: 'Refocused to home' }).click(); | ||
| }); | ||
|
|
||
| test('Verify minimap toggle functionality', async ({ page }) => { | ||
| const minimap = page.locator('.react-flow__minimap'); | ||
| await expect(minimap).toBeVisible(); | ||
|
|
||
| await page.getByTestId('toggle-mind-map').click(); | ||
| await expect(minimap).not.toBeVisible(); | ||
|
|
||
| await page.getByTestId('toggle-mind-map').click(); | ||
| await expect(minimap).toBeVisible(); | ||
| }); | ||
|
|
||
| test('Verify fullscreen toggle', async ({ page }) => { | ||
| // before each step has fullscreen=true | ||
| expect(page.url()).toContain('fullscreen=true'); | ||
|
|
||
| await page.getByTestId('exit-full-screen').click(); | ||
|
|
||
| expect(page.url()).not.toContain('fullscreen=true'); | ||
| await page.getByTestId('full-screen').click(); | ||
|
|
||
| expect(page.url()).toContain('fullscreen=true'); | ||
| }); | ||
| }); | ||
|
|
||
| test.describe('Lineage Layers', () => { | ||
| test.describe('Data Observability Layer', () => { | ||
| test.beforeEach(async ({ page }) => { | ||
| await table.visitEntityPage(page); | ||
| await visitLineageTab(page); | ||
| await performZoomOut(page); | ||
| }); | ||
|
|
||
| test('Verify DQ layer toggle activation', async ({ page }) => { | ||
| await page.getByTestId('lineage-layer-btn').click(); | ||
|
|
||
| const observabilityBtn = page.getByTestId( | ||
| 'lineage-layer-observability-btn' | ||
| ); | ||
| await expect(observabilityBtn).toBeVisible(); | ||
|
|
||
| await expect(observabilityBtn).not.toHaveClass(/Mui-selected/); | ||
|
|
||
| await observabilityBtn.click(); | ||
| await page.keyboard.press('Escape'); | ||
|
|
||
| await page.getByTestId('lineage-layer-btn').click(); | ||
| await expect(observabilityBtn).toHaveClass(/Mui-selected/); | ||
| }); | ||
|
|
||
| test('Verify DQ layer toggle off removes highlights', async ({ page }) => { | ||
| await page.getByTestId('lineage-layer-btn').click(); | ||
|
|
||
| const observabilityBtn = page.getByTestId( | ||
| 'lineage-layer-observability-btn' | ||
| ); | ||
|
|
||
| await observabilityBtn.click(); | ||
| await page.keyboard.press('Escape'); | ||
|
|
||
| await page.getByTestId('lineage-layer-btn').click(); | ||
| await expect(observabilityBtn).toHaveClass(/Mui-selected/); | ||
|
|
||
| await observabilityBtn.click(); | ||
| await page.keyboard.press('Escape'); | ||
|
|
||
| await page.getByTestId('lineage-layer-btn').click(); | ||
| await expect(observabilityBtn).not.toHaveClass(/Mui-selected/); | ||
| }); | ||
| }); | ||
|
|
||
| test.describe('Error Handling', () => { | ||
| test('Verify invalid entity search handling', async ({ page }) => { | ||
| await sidebarClick(page, SidebarItem.LINEAGE); | ||
|
|
||
| await waitForAllLoadersToDisappear(page); | ||
|
|
||
| const searchSelect = page.getByTestId('search-entity-select'); | ||
| await expect(searchSelect).toBeVisible(); | ||
|
|
||
| await searchSelect.click(); | ||
|
|
||
| await page | ||
| .locator( | ||
| '[data-testid="search-entity-select"] .ant-select-selection-search-input' | ||
| ) | ||
| .fill('invalid_fqn_does_not_exist_12345'); | ||
|
|
||
| const noResultsText = page.getByText(/no match/i); | ||
| if ((await noResultsText.count()) > 0) { | ||
| await expect(noResultsText).toBeVisible(); | ||
| } | ||
| }); | ||
|
|
||
| test('Verify lineage tab with no lineage data', async ({ page }) => { | ||
| const emptyTable = new TableClass(); | ||
| const { apiContext, afterAction } = await getApiContext(page); | ||
|
|
||
| await emptyTable.create(apiContext); | ||
|
|
||
| await emptyTable.visitEntityPage(page); | ||
| await visitLineageTab(page); | ||
|
|
||
| await waitForAllLoadersToDisappear(page); | ||
|
|
||
| const tableFqn = get(emptyTable, 'entityResponseData.fullyQualifiedName'); | ||
| const tableNode = page.getByTestId(`lineage-node-${tableFqn}`); | ||
| await expect(tableNode).toBeVisible(); | ||
|
|
||
| await emptyTable.delete(apiContext); | ||
| await afterAction(); | ||
| }); | ||
| }); | ||
| }); | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.