Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
9dab02c
test(ui): re-enable Domains, Data Product & domain-rename E2E suites
siddhant1 Jul 24, 2026
f6b295e
Merge remote-tracking branch 'origin/main' into sid/reenable-domains-…
siddhant1 Jul 24, 2026
38f258d
Merge branch 'main' into sid/reenable-domains-dataproducts-e2e
siddhant1 Jul 24, 2026
660fd08
Merge branch 'main' into sid/reenable-domains-dataproducts-e2e
siddhant1 Jul 24, 2026
9890906
Merge branch 'main' into sid/reenable-domains-dataproducts-e2e
siddhant1 Jul 24, 2026
e969a37
Merge branch 'main' into sid/reenable-domains-dataproducts-e2e
siddhant1 Jul 24, 2026
4edf1b7
Merge branch 'main' into sid/reenable-domains-dataproducts-e2e
siddhant1 Jul 27, 2026
34723c4
Merge branch 'main' into sid/reenable-domains-dataproducts-e2e
siddhant1 Jul 27, 2026
97c16d9
Merge branch 'main' into sid/reenable-domains-dataproducts-e2e
siddhant1 Jul 27, 2026
fbe8739
Merge branch 'main' into sid/reenable-domains-dataproducts-e2e
siddhant1 Jul 28, 2026
712f65d
Merge branch 'main' into sid/reenable-domains-dataproducts-e2e
siddhant1 Jul 28, 2026
a5dcad0
Merge branch 'main' into sid/reenable-domains-dataproducts-e2e
siddhant1 Jul 29, 2026
87186c2
fix(e2e): repair three specs that broke against current main
siddhant1 Jul 29, 2026
942291f
Merge branch 'main' into sid/reenable-domains-dataproducts-e2e
siddhant1 Jul 30, 2026
2afe91b
ci(playwright): track the 25m shard wrapper in the perf gate
siddhant1 Jul 31, 2026
089675a
ci(playwright): give shards 30m and keep the gates tracking the wrapper
siddhant1 Jul 31, 2026
20724d5
Merge branch 'main' into sid/reenable-domains-dataproducts-e2e
siddhant1 Jul 31, 2026
2e9b1cd
ci(playwright): restore real weights for re-enabled specs in the timi…
siddhant1 Jul 31, 2026
f0217b9
Merge remote-tracking branch 'origin/sid/reenable-domains-dataproduct…
siddhant1 Jul 31, 2026
90c549b
Revert "ci(playwright): restore real weights for re-enabled specs in …
siddhant1 Jul 31, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -643,8 +643,7 @@ test.describe(
// DOMAIN TESTS
// ===================================================================

// eslint-disable-next-line playwright/no-skipped-test -- domain rename consolidation not yet stable
test.skip('Domain - rename then update description should work', async ({
test('Domain - rename then update description should work', async ({
page,
browser,
}) => {
Expand Down Expand Up @@ -699,8 +698,7 @@ test.describe(
}
});

// eslint-disable-next-line playwright/no-skipped-test -- domain rename consolidation not yet stable
test.skip('Domain - multiple rename + update cycles should work', async ({
test('Domain - multiple rename + update cycles should work', async ({
page,
browser,
}) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -228,9 +228,7 @@ test.describe('Glossary Navigation', () => {
});

// UI-01: Empty glossary state (no terms)
// Skip: Test isolation issue - selectActiveGlossary not selecting the correct glossary
// eslint-disable-next-line playwright/no-skipped-test -- test isolation issue with selectActiveGlossary
test.skip('should show empty state when glossary has no terms', async ({
test('should show empty state when glossary has no terms', async ({
page,
}) => {
const { apiContext, afterAction } = await getApiContext(page);
Expand All @@ -243,8 +241,11 @@ test.describe('Glossary Navigation', () => {
await sidebarClick(page, SidebarItem.GLOSSARY);
await selectActiveGlossary(page, emptyGlossary.data.displayName);

// Verify empty state is shown (with default status filter active)
await expect(page.getByText('No Glossary Term found')).toBeVisible();
// A glossary with zero terms renders the empty-glossary placeholder, not
// the "No Glossary Term found" row that a non-matching status filter shows.
await expect(
page.getByTestId('create-error-placeholder-Glossary Term')
).toBeVisible();

// Verify add term button is available
await expect(page.getByTestId('add-new-tag-button-header')).toBeVisible();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { expect, Page, test as base } from '@playwright/test';
import { Page, test as base } from '@playwright/test';
import { SidebarItem } from '../../../constant/sidebar';
import { DataProduct } from '../../../support/domain/DataProduct';
import { Domain } from '../../../support/domain/Domain';
Expand Down Expand Up @@ -59,7 +59,7 @@

const test = base.extend<{ page: Page }>({
page: async ({ browser }, use) => {
const page = await browser.newPage();

Check warning on line 62 in openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/LandingPageWidgets/DomainDataProductsWidgets.spec.ts

View workflow job for this annotation

GitHub Actions / checkstyle

Prefer the `page` fixture (test.use({ storageState })) over browser.newPage() + manual login for single-user admin tests. For multi-user tests that need a second non-admin page, this warning is expected — no action needed
await adminUser.login(page);
await use(page);
await page.close();
Expand Down Expand Up @@ -91,7 +91,7 @@
await afterAction();
});

test.describe.fixme('Domain and Data Product Asset Counts', () => {
test.describe.serial('Domain and Data Product Asset Counts', () => {
test.slow(); // Slow Test
test.beforeEach(async ({ page }, testInfo) => {
await redirectToHomePage(page, false);
Expand Down Expand Up @@ -265,46 +265,25 @@
await page.getByTestId('assets').click();
await dataProductAssetsResponse;

let hasAssets = true;
while (hasAssets) {
const checkboxes = page.locator(
'[data-testid^="table-data-card_"] input[type="checkbox"]'
);
const count = await checkboxes.count();

if (count === 0) {
hasAssets = false;
break;
}

const selectAll = page.getByRole('checkbox', { name: 'Select All' });
if (await selectAll.isVisible()) {
await selectAll.check();
} else {
for (let i = 0; i < count; i++) {
await checkboxes.nth(i).check();
}
}

const previousCount = count;
const removeRes = page.waitForResponse('**/assets/remove');
await page.getByTestId('delete-all-button').click();
await removeRes;
// Remove every asset currently attached to the data product. The card
// list paints asynchronously after the assets response resolves, and
// count() does not auto-wait — so wait for the first card to render
// before counting, otherwise the loop reads 0 and removes nothing.
await waitForAllLoadersToDisappear(page);
const assetCard = page.locator('[data-testid^="table-data-card_"]');
await assetCard.first().waitFor({ state: 'visible' });

await expect
.poll(
async () =>
page
.locator(
'[data-testid^="table-data-card_"] input[type="checkbox"]'
)
.count(),
{ timeout: 10_000 }
)
.toBeLessThan(previousCount);
const attachedCount = await assetCard.count();
for (let i = 0; i < attachedCount; i++) {
await assetCard.nth(i).locator('input[type="checkbox"]').check();
}

const removeRes = page.waitForResponse('**/assets/remove');
await page.getByTestId('delete-all-button').click();
await removeRes;

await page.reload();
await waitForAllLoadersToDisappear(page);
await checkAssetsCount(page, 0);

await redirectToHomePage(page);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,14 +110,14 @@
await afterAction();
},
userPage: async ({ browser }, setPage) => {
const page = await browser.newPage();

Check warning on line 113 in openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/Domains.spec.ts

View workflow job for this annotation

GitHub Actions / checkstyle

Prefer the `page` fixture (test.use({ storageState })) over browser.newPage() + manual login for single-user admin tests. For multi-user tests that need a second non-admin page, this warning is expected — no action needed
await user.login(page);
await setPage(page);
await page.close();
},
});

test.describe.fixme('Domains', () => {
test.describe('Domains', () => {
test.slow(true);

test.beforeAll('Setup pre-requests', async ({ browser }) => {
Expand Down Expand Up @@ -384,16 +384,17 @@
// Verify empty state message
await expect(page.getByTestId('empty-placeholder')).toBeVisible();

const addButton = page.getByTestId('data-assets-add-button');
// `CreatePlaceholder` applies the action's `data-assets-add-button` as the
// button's DOM id, so this CTA has no testid to select it by.
const addButton = page.locator('#data-assets-add-button');
await expect(addButton).toBeVisible();
await addButton.click();

await waitForAllLoadersToDisappear(page);

// Verify Add Assets form is displayed
await expect(page.getByTestId('form-heading')).toContainText(
'Add Assets'
);
// Verify Add Assets modal is displayed (migrated to the core-ui Dialog
// `asset-selection-modal`; the old `form-heading` testid no longer applies)
await expect(page.getByTestId('asset-selection-modal')).toBeVisible();

await expect(page.getByTestId('cancel-btn')).toBeVisible();
await expect(page.getByTestId('save-btn')).toBeDisabled();
Expand Down Expand Up @@ -1698,7 +1699,7 @@
});
});

test.describe.fixme('Domain Rename Comprehensive Tests', () => {
test.describe('Domain Rename Comprehensive Tests', () => {
test.slow(true);

test.beforeEach('Visit home page', async ({ page }) => {
Expand Down Expand Up @@ -2721,7 +2722,7 @@
});
});

test.describe.fixme('Domains Rbac', () => {
test.describe('Domains Rbac', () => {
test.slow(true);

let domain1: Domain;
Expand Down Expand Up @@ -2877,7 +2878,7 @@
});
});

test.describe.fixme('Data Consumer Domain Ownership', () => {
test.describe('Data Consumer Domain Ownership', () => {
test.slow(true);

let classification: ClassificationClass;
Expand Down Expand Up @@ -2976,7 +2977,7 @@
});
});

test.describe.fixme('Domain Access with hasDomain() Rule', () => {
test.describe('Domain Access with hasDomain() Rule', () => {
test.slow(true);

let testResources: {
Expand Down Expand Up @@ -3045,7 +3046,7 @@
});
});

test.describe.fixme('Domain Access with noDomain() Rule', () => {
test.describe('Domain Access with noDomain() Rule', () => {
test.slow(true);

let testResources: {
Expand Down Expand Up @@ -3119,7 +3120,7 @@
});
});

test.describe.fixme('Domain Tree View Functionality', () => {
test.describe('Domain Tree View Functionality', () => {
let subDomain: SubDomain;
const domain = EntityDataClass.domain1;
const domainDisplayName = domain.responseData.displayName;
Expand Down Expand Up @@ -3149,7 +3150,7 @@
await sidebarClick(page, SidebarItem.DOMAIN);
await waitForAllLoadersToDisappear(page);

const treeViewButton = page.getByRole('button', { name: 'tree' });
const treeViewButton = page.getByRole('radio', { name: 'tree' });
await expect(treeViewButton).toBeVisible();
await treeViewButton.click();

Expand Down Expand Up @@ -3392,7 +3393,7 @@
});
});

test.describe.fixme('Domain asset dryRun — add confirmation', () => {
test.describe('Domain asset dryRun — add confirmation', () => {
test.slow(true);

const openDomainAssetsAddModal = async (page: Page, domain: Domain) => {
Expand Down Expand Up @@ -3653,78 +3654,75 @@
});
});

test.describe.fixme(
'Domain assets — glossary and inherited glossary term',
() => {
test.slow(true);
test.describe('Domain assets — glossary and inherited glossary term', () => {
test.slow(true);

let assetDomain: Domain;
let assetGlossary: Glossary;
let inheritedTerm: GlossaryTerm;
let assetDomain: Domain;
let assetGlossary: Glossary;
let inheritedTerm: GlossaryTerm;

test.beforeAll(
'Setup domain with glossary and inherited term',
async ({ browser }) => {
const { apiContext, afterAction } = await performAdminLogin(browser);
test.beforeAll(
'Setup domain with glossary and inherited term',
async ({ browser }) => {
const { apiContext, afterAction } = await performAdminLogin(browser);

assetDomain = new Domain();
assetGlossary = new Glossary();
assetDomain = new Domain();
assetGlossary = new Glossary();

await assetDomain.create(apiContext);
await assetGlossary.create(apiContext);
await assetDomain.create(apiContext);
await assetGlossary.create(apiContext);

await assetGlossary.patch(apiContext, [
{
op: 'add',
path: '/domains/0',
value: {
id: assetDomain.responseData.id,
type: 'domain',
name: assetDomain.responseData.name,
displayName: assetDomain.responseData.displayName,
},
await assetGlossary.patch(apiContext, [
{
op: 'add',
path: '/domains/0',
value: {
id: assetDomain.responseData.id,
type: 'domain',
name: assetDomain.responseData.name,
displayName: assetDomain.responseData.displayName,
},
]);

inheritedTerm = new GlossaryTerm(assetGlossary);
await inheritedTerm.create(apiContext);
},
]);

await afterAction();
}
);
inheritedTerm = new GlossaryTerm(assetGlossary);
await inheritedTerm.create(apiContext);

test.afterAll('Cleanup', async ({ browser }) => {
const { apiContext, afterAction } = await performAdminLogin(browser);
await inheritedTerm.delete(apiContext);
await assetGlossary.delete(apiContext);
await assetDomain.delete(apiContext);
await afterAction();
});
}
);

test.beforeEach('Visit home page', async ({ page }) => {
await redirectToHomePage(page);
});
test.afterAll('Cleanup', async ({ browser }) => {
const { apiContext, afterAction } = await performAdminLogin(browser);
await inheritedTerm.delete(apiContext);
await assetGlossary.delete(apiContext);
await assetDomain.delete(apiContext);
await afterAction();
});

test('Assets tab lists the assigned glossary and its inherited term', async ({
page,
}) => {
await sidebarClick(page, SidebarItem.DOMAIN);
await waitForAllLoadersToDisappear(page);
test.beforeEach('Visit home page', async ({ page }) => {
await redirectToHomePage(page);
});

await goToAssetsTab(page, assetDomain.data);
test('Assets tab lists the assigned glossary and its inherited term', async ({
page,
}) => {
await sidebarClick(page, SidebarItem.DOMAIN);
await waitForAllLoadersToDisappear(page);

const glossaryCard = page.getByTestId(
`table-data-card_${assetGlossary.responseData.fullyQualifiedName}`
);
const inheritedTermCard = page.getByTestId(
`table-data-card_${inheritedTerm.responseData.fullyQualifiedName}`
);
await goToAssetsTab(page, assetDomain.data);

await expect(glossaryCard).toBeVisible({ timeout: 30_000 });
await expect(inheritedTermCard).toBeVisible({ timeout: 30_000 });
});
}
);
const glossaryCard = page.getByTestId(
`table-data-card_${assetGlossary.responseData.fullyQualifiedName}`
);
const inheritedTermCard = page.getByTestId(
`table-data-card_${inheritedTerm.responseData.fullyQualifiedName}`
);

await expect(glossaryCard).toBeVisible({ timeout: 30_000 });
await expect(inheritedTermCard).toBeVisible({ timeout: 30_000 });
});
});

test.describe('Domain description editor popups', () => {
const table = new TableClass();
Expand Down
Loading
Loading