feat: Add Playwright test tagging and enhance documentation generation with tag support. (#24993)

* feat: Add Playwright test tagging and enhance documentation generation with tag support.

* feat: Enable manual workflow dispatch for SSO tests and add type assertion for table columns in data quality tests.

* addressing comments
This commit is contained in:
Shailesh Parmar 2025-12-27 19:05:07 +05:30 committed by GitHub
parent dfd82688e8
commit 6dde0843b7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 321 additions and 220 deletions

View File

@ -38,7 +38,7 @@
"playwright:open": "playwright test --ui",
"playwright:codegen": "playwright codegen",
"generate:app-docs": "node generateApplicationDocs.js",
"generate:e2e-docs": "node playwright/doc-generator/generate.js"
"generate:e2e-docs": "PLAYWRIGHT_IS_OSS=true node playwright/doc-generator/generate.js"
},
"dependencies": {
"@analytics/session-utils": "^0.1.17",

View File

@ -14,3 +14,11 @@
export const PLAYWRIGHT_INGESTION_TAG_OBJ = {
tag: '@ingestion',
};
export const DOMAIN_TAGS = {
GOVERNANCE: '@Governance',
DISCOVERY: '@Discovery',
PLATFORM: '@Platform',
OBSERVABILITY: '@Observability',
INTEGRATION: '@Integration',
};

View File

@ -17,8 +17,8 @@ const { execSync } = require('child_process');
const { generateDomainMarkdown, generateIndexMarkdown } = require('./markdown.js');
const { loadTestsFromPlaywright } = require('./playwright-loader.js');
// Constants
// Script is in: openmetadata-ui/src/main/resources/ui/playwright/doc-generator/
// Constants for Default Run
const DEFAULT_REPO_BASE_URL = 'https://github.com/open-metadata/OpenMetadata';
const PLAYWRIGHT_DIR = path.resolve(__dirname, '../e2e');
const OUTPUT_DIR = path.resolve(__dirname, '../docs');
@ -114,35 +114,58 @@ const DOMAIN_MAPPING = {
'Service': { domain: 'Integration', name: 'Connectors' },
'Ingestion': { domain: 'Integration', name: 'Connectors' },
'Query': { domain: 'Integration', name: 'Connectors' }, // QueryEntity
'ApiCollection': { domain: 'Integration', name: 'Connectors' },
};
function getComponentInfo(fileName) {
for (const [key, def] of Object.entries(DOMAIN_MAPPING)) {
function getComponentInfo(fileName, domainMapping, tags = []) {
// 1. Check Tags first (highest priority)
// Tags should be like "@Domain:Component" or just "@Domain"
for (const tag of tags) {
// Remove @ if present
const cleanTag = tag.startsWith('@') ? tag.substring(1) : tag;
// Check if tag matches a known domain mapping key directly
if (domainMapping[cleanTag]) {
return domainMapping[cleanTag];
}
}
// 2. Fallback to Filename matching
for (const [key, def] of Object.entries(domainMapping)) {
if (fileName.includes(key)) return def;
}
return { domain: 'Platform', name: 'Other' };
}
function main() {
/**
* Main Generation Logic
* @param {Object} options - Configuration options
* @param {string} options.playwrightDir - Path to Playwright tests
* @param {string} options.outputDir - Output path for docs
* @param {string} options.repoBaseUrl - Base URL for Git links (e.g. GitHub blob)
* @param {Object} options.domainMapping - Mapping of files to components
*/
function generateDocs({ playwrightDir, outputDir, repoBaseUrl, domainMapping }) {
console.log(`🚀 Starting Documentation Generation (Node.js)`);
console.log(` Input: ${PLAYWRIGHT_DIR}`);
console.log(` Output: ${OUTPUT_DIR}`);
console.log(` Input: ${playwrightDir}`);
console.log(` Output: ${outputDir}`);
console.log(` Repo Base: ${repoBaseUrl}`);
if (!fs.existsSync(PLAYWRIGHT_DIR)) {
if (!fs.existsSync(playwrightDir)) {
console.error(`❌ Playwright directory not found!`);
process.exit(1);
}
// 1. Find and Parse Files using Native Playwright Loader
console.log(`📝 asking Playwright to list tests...`);
const parsedFiles = loadTestsFromPlaywright(PLAYWRIGHT_DIR);
const parsedFiles = loadTestsFromPlaywright(playwrightDir);
console.log(` Received ${parsedFiles.length} file suites from Playwright.`);
// 2. Group by Domain + Component
const groupings = new Map();
parsedFiles.forEach(file => {
const { domain, name } = getComponentInfo(file.fileName);
const { domain, name } = getComponentInfo(file.fileName, domainMapping, file.tags);
const key = `${domain}:${name}`;
if (!groupings.has(key)) {
@ -166,10 +189,10 @@ function main() {
console.log(`⚙️ Generating Markdown for ${components.length} components...`);
// Clean output directory
if (fs.existsSync(OUTPUT_DIR)) {
fs.rmSync(OUTPUT_DIR, { recursive: true, force: true });
if (fs.existsSync(outputDir)) {
fs.rmSync(outputDir, { recursive: true, force: true });
}
fs.mkdirSync(OUTPUT_DIR, { recursive: true });
fs.mkdirSync(outputDir, { recursive: true });
// Stats
const stats = {
@ -188,27 +211,41 @@ function main() {
// Generate Consolidated Domain Pages
Object.entries(componentsByDomain).forEach(([domain, comps]) => {
const content = generateDomainMarkdown(domain, comps);
fs.writeFileSync(path.join(OUTPUT_DIR, `${domain}.md`), content);
const content = generateDomainMarkdown(domain, comps, { repoBaseUrl });
fs.writeFileSync(path.join(outputDir, `${domain}.md`), content);
console.log(`${domain}.md`);
});
// Generate Main Index (README.md)
fs.writeFileSync(path.join(OUTPUT_DIR, 'README.md'), generateIndexMarkdown(components, stats));
fs.writeFileSync(path.join(outputDir, 'README.md'), generateIndexMarkdown(components, stats));
console.log(` ✓ README.md`);
// 5. Stage files in Git
try {
console.log(`\n📦 Staging generated docs...`);
execSync('git add .', { cwd: OUTPUT_DIR, stdio: 'inherit' });
console.log(` ✓ git add completed for ${OUTPUT_DIR}`);
execSync('git add .', { cwd: outputDir, stdio: 'inherit' });
console.log(` ✓ git add completed for ${outputDir}`);
} catch (error) {
console.error(` ⚠️ Warning: Failed to stage files with git.`);
console.error(error.message);
}
console.log(`\n✅ Success! Documentation generated in:`);
console.log(` ${OUTPUT_DIR}`);
console.log(` ${outputDir}`);
}
main();
// Check if run directly
if (require.main === module) {
generateDocs({
playwrightDir: PLAYWRIGHT_DIR,
outputDir: OUTPUT_DIR,
repoBaseUrl: DEFAULT_REPO_BASE_URL,
domainMapping: DOMAIN_MAPPING
});
}
module.exports = {
generateDocs,
DOMAIN_MAPPING
};

View File

@ -11,8 +11,6 @@
* limitations under the License.
*/
const REPO_BASE_URL = 'https://github.com/open-metadata/OpenMetadata';
/**
* Generate the Main Index Page (README.md)
*/
@ -134,7 +132,9 @@ function generateIndexMarkdown(components, stats) {
/**
* Generate a Consolidated Domain Page
*/
function generateDomainMarkdown(domainName, components) {
function generateDomainMarkdown(domainName, components, options = {}) {
const { repoBaseUrl } = options;
// Stats for the Domain
const totalTests = components.reduce((s, c) => s + c.totalTests, 0);
const totalFiles = components.reduce((s, c) => s + c.files.length, 0);
@ -175,7 +175,7 @@ function generateDomainMarkdown(domainName, components) {
const sortedFiles = [...component.files].sort((a, b) => b.totalScenarios - a.totalScenarios);
sortedFiles.forEach(file => {
md += renderFileWithCollapse(file);
md += renderFileWithCollapse(file, repoBaseUrl);
});
md += `\n---\n\n`;
@ -184,9 +184,30 @@ function generateDomainMarkdown(domainName, components) {
return md;
}
function renderFileWithCollapse(file) {
const relativePath = file.path.split('openmetadata-ui/')[1] || file.path;
const fileUrl = `${REPO_BASE_URL}/blob/main/openmetadata-ui/${relativePath}`;
function renderFileWithCollapse(file, repoBaseUrl) {
// Try to find relative path from 'src/main/resources/ui' or similar common roots if possible,
// or fall back to just filename if path parsing is complex.
// Assuming standard Maven structure: .../src/main/resources/ui/...
// Robust path logic for both OpenMetadata (monorepo) and Collate (separate repo)
// Goal: relativePath should be 'src/main/resources/ui/...' to match standard docs
let relativePath = file.path;
const standardPrefix = 'src/main/resources/ui/';
if (file.path.includes('openmetadata-ui/')) {
// Standard OM case: path contains 'openmetadata-ui/src/main/resources/ui/...'
relativePath = file.path.split('openmetadata-ui/')[1];
} else if (file.path.includes(standardPrefix)) {
// Collate/Fallback case: path contains 'src/main/resources/ui/...' but maybe not 'openmetadata-ui/'
// We normalize it to start with src/main/resources/ui/
relativePath = standardPrefix + file.path.split(standardPrefix)[1];
// Ensure no double slashes from split
relativePath = relativePath.replace('//', '/');
}
// URL Construction assuming 'openmetadata-ui' is the root module folder in both repos
const fileUrl = `${repoBaseUrl}/blob/main/openmetadata-ui/${relativePath.startsWith('/') ? relativePath.substring(1) : relativePath}`;
// Calculate File Scenarios
let fileScenarios = 0;

View File

@ -290,6 +290,7 @@ function flattenTests(suite, testDir) {
line: specLine,
description: description,
steps: steps,
tags: spec.tags || [],
isSkipped: false // We can check spec.tests[0].status or annotations
});
});
@ -351,9 +352,16 @@ function loadTestsFromPlaywright(testDir) {
});
}
// Calculate totals
// Calculate totals and collect tags
let totalTests = rootTests.length;
describes.forEach(d => totalTests += d.tests.length);
const fileTags = new Set();
rootTests.forEach(t => t.tags && t.tags.forEach(tag => fileTags.add(tag)));
describes.forEach(d => {
totalTests += d.tests.length;
d.tests.forEach(t => t.tags && t.tags.forEach(tag => fileTags.add(tag)));
});
return {
path: filePath,
@ -362,7 +370,8 @@ function loadTestsFromPlaywright(testDir) {
totalSteps: 0,
totalScenarios: totalTests,
rootTests: rootTests,
describes: describes
describes: describes,
tags: Array.from(fileTags)
};
}

View File

@ -2,13 +2,13 @@
# Governance
> **6 Components** | **41 Files** | **669 Tests** | **1104 Scenarios** 🚀
> **6 Components** | **42 Files** | **671 Tests** | **1111 Scenarios** 🚀
## Table of Contents
- [Custom Properties](#custom-properties)
- [Metrics](#metrics)
- [Glossary](#glossary)
- [Domains & Data Products](#domains-data-products)
- [Glossary](#glossary)
- [Tags](#tags)
- [Data Contracts](#data-contracts)
@ -455,6 +455,175 @@
</details>
---
<div id="domains-data-products"></div>
## Domains & Data Products
<details open>
<summary>📄 <b>Domains.spec.ts</b> (26 tests, 45 scenarios)</summary>
> Source: [`src/main/resources/ui/playwright/e2e/Pages/Domains.spec.ts`](https://github.com/open-metadata/OpenMetadata/blob/main/openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/Domains.spec.ts)
### Domains
| # | Test Case | Description |
|---|-----------|-------------|
| 1 | **Domains** - Create domains and add assets | Create domains and add assets |
| | ↳ *Create domain* | |
| | ↳ *Add assets to domain* | |
| | ↳ *Delete domain using delete modal* | |
| 2 | **Domains** - Create DataProducts and add remove assets | Create DataProducts and add remove assets |
| | ↳ *Add assets to domain* | |
| | ↳ *Create DataProducts* | |
| | ↳ *Follow & Un-follow DataProducts* | |
| | ↳ *Verify empty assets message and Add Asset button* | |
| | ↳ *Add assets to DataProducts* | |
| | ↳ *Remove assets from DataProducts* | |
| 3 | **Domains** - Follow & Un-follow domain | Follow & Un-follow domain |
| 4 | **Domains** - Add, Update custom properties for data product | Add, Update custom properties for data product |
| | ↳ *Create DataProduct and custom properties for it* | |
| | ↳ *Set ${...} Custom Property* | |
| | ↳ *Update ${...} Custom Property* | |
| 5 | **Domains** - Switch domain from navbar and check domain query call wrap in quotes | Switch domain from navbar and check domain query call wrap in quotes |
| 6 | **Domains** - Rename domain | Rename domain |
| 7 | **Domains** - Follow/unfollow subdomain and create nested sub domain | Follow/unfollow subdomain and create nested sub domain |
| 8 | **Domains** - Should clear assets from data products after deletion of data product in Domain | Clear assets from data products after deletion of data product in Domain |
| | ↳ *Delete domain & recreate the same domain and data product* | |
| 9 | **Domains** - Should inherit owners and experts from parent domain | Inherit owners and experts from parent domain |
| 10 | **Domains** - Domain owner should able to edit description of domain | Domain owner should able to edit description of domain |
| 11 | **Domains** - Verify domain and subdomain asset count accuracy | Domain and subdomain asset count accuracy |
| | ↳ *Create domain and subdomain via API* | |
| | ↳ *Add assets to domain* | |
| | ↳ *Add assets to subdomain* | |
| | ↳ *Verify domain asset count matches displayed cards* | |
| | ↳ *Verify subdomain asset count matches displayed cards* | |
| 12 | **Domains** - Verify domain tags and glossary terms | Domain tags and glossary terms |
| 13 | **Domains** - Verify data product tags and glossary terms | Data product tags and glossary terms |
| 14 | **Domains** - Verify clicking All Domains sets active domain to default value | Clicking All Domains sets active domain to default value |
| 15 | **Domains** - Verify redirect path on data product delete | Redirect path on data product delete |
| 16 | **Domains** - Verify duplicate domain creation | Duplicate domain creation |
| 17 | **Domains** - Create domain custom property and verify value persistence | Create domain custom property and verify value persistence |
| | ↳ *Create custom property for domain entity* | |
| | ↳ *Navigate to domain and assign custom property value* | |
| | ↳ *Reload and verify custom property value persists* | |
| | ↳ *Cleanup custom property* | |
| 18 | **Domains** - Domain announcement create, edit & delete | Domain announcement create, edit & delete |
| 19 | **Domains** - Data Product announcement create, edit & delete | Data Product announcement create, edit & delete |
| 20 | **Domains** - should handle domain after description is deleted | Tests that verify UI handles entities with deleted descriptions gracefully. The issue occurs when: 1. An entity is created with a description 2. The description is later deleted/cleared via API patch 3. The API returns the entity without a description field (due to @JsonInclude(NON_NULL)) 4. UI should handle this gracefully instead of crashing |
| 21 | **Domains** - should handle data product after description is deleted | Handle data product after description is deleted |
### Domains Rbac
| # | Test Case | Description |
|---|-----------|-------------|
| 1 | **Domains Rbac** - Domain Rbac | Domain Rbac |
| | ↳ *Assign assets to domains* | |
| | ↳ *User with access to multiple domains* | |
### Data Consumer Domain Ownership
| # | Test Case | Description |
|---|-----------|-------------|
| 1 | **Data Consumer Domain Ownership** - Data consumer can manage domain as owner | Data consumer can manage domain as owner |
| | ↳ *Check domain management permissions for data consumer owner* | |
### Domain Access with hasDomain() Rule
| # | Test Case | Description |
|---|-----------|-------------|
| 1 | **Domain Access with hasDomain() Rule** - User with hasDomain() rule can access domain and subdomain assets | User with hasDomain() rule can access domain and subdomain assets |
| | ↳ *Verify user can access domain assets* | |
| | ↳ *Verify user can access subdomain assets* | |
### Domain Access with noDomain() Rule
| # | Test Case | Description |
|---|-----------|-------------|
| 1 | **Domain Access with noDomain() Rule** - User with noDomain() rule cannot access tables without domain | User with noDomain() rule cannot access tables without domain |
| | ↳ *Verify user can access domain-assigned table* | |
| | ↳ *Verify user gets permission error for table without domain* | |
### Domain Tree View Functionality
| # | Test Case | Description |
|---|-----------|-------------|
| 1 | **Domain Tree View Functionality** - should render the domain tree view with correct details | Render the domain tree view with correct details |
</details>
<details open>
<summary>📄 <b>DomainDataProductsWidgets.spec.ts</b> (6 tests, 6 scenarios)</summary>
> Source: [`src/main/resources/ui/playwright/e2e/Features/LandingPageWidgets/DomainDataProductsWidgets.spec.ts`](https://github.com/open-metadata/OpenMetadata/blob/main/openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/LandingPageWidgets/DomainDataProductsWidgets.spec.ts)
### Domain and Data Product Asset Counts
| # | Test Case | Description |
|---|-----------|-------------|
| 1 | **Domain and Data Product Asset Counts** - Assign Widgets | Assign Widgets |
| 2 | **Domain and Data Product Asset Counts** - Verify Widgets are having 0 count initially | Widgets are having 0 count initially |
| 3 | **Domain and Data Product Asset Counts** - Domain asset count should update when assets are added | Domain asset count should update when assets are added |
| 4 | **Domain and Data Product Asset Counts** - Data Product asset count should update when assets are added | Data Product asset count should update when assets are added |
| 5 | **Domain and Data Product Asset Counts** - Domain asset count should update when assets are removed | Domain asset count should update when assets are removed |
| 6 | **Domain and Data Product Asset Counts** - Data Product asset count should update when assets are removed | Data Product asset count should update when assets are removed |
</details>
<details open>
<summary>📄 <b>DataProductPersonaCustomization.spec.ts</b> (2 tests, 7 scenarios)</summary>
> Source: [`src/main/resources/ui/playwright/e2e/Features/DataProductPersonaCustomization.spec.ts`](https://github.com/open-metadata/OpenMetadata/blob/main/openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/DataProductPersonaCustomization.spec.ts)
### Data Product Persona customization
| # | Test Case | Description |
|---|-----------|-------------|
| 1 | **Data Product Persona customization** - Data Product - customization should work | Data Product - customization should work |
| | ↳ *pre-requisite* | |
| | ↳ *should show all the tabs & widget as default when no customization is done* | |
| | ↳ *apply customization* | |
| | ↳ *Validate customization* | |
| 2 | **Data Product Persona customization** - Data Product - customize tab label should only render if it's customized by user | Data Product - customize tab label should only render if it's customized by user |
| | ↳ *pre-requisite* | |
| | ↳ *apply tab label customization for Data Product* | |
| | ↳ *validate applied label change for Data Product Documentation tab* | |
</details>
<details open>
<summary>📄 <b>DomainPermissions.spec.ts</b> (2 tests, 2 scenarios)</summary>
> Source: [`src/main/resources/ui/playwright/e2e/Features/Permissions/DomainPermissions.spec.ts`](https://github.com/open-metadata/OpenMetadata/blob/main/openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Permissions/DomainPermissions.spec.ts)
### Standalone Tests
| # | Test Case | Description |
|---|-----------|-------------|
| 1 | Domain allow operations | Domain allow operations |
| 2 | Domain deny operations | Domain deny operations |
</details>
<details open>
<summary>📄 <b>SubDomainPagination.spec.ts</b> (1 tests, 4 scenarios)</summary>
> Source: [`src/main/resources/ui/playwright/e2e/Pages/SubDomainPagination.spec.ts`](https://github.com/open-metadata/OpenMetadata/blob/main/openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/SubDomainPagination.spec.ts)
### SubDomain Pagination
| # | Test Case | Description |
|---|-----------|-------------|
| 1 | **SubDomain Pagination** - Verify subdomain count and pagination functionality | Subdomain count and pagination functionality |
| | ↳ *Verify subdomain count in tab label* | |
| | ↳ *Navigate to subdomains tab and verify initial data load* | |
| | ↳ *Test pagination navigation* | |
| | ↳ *Create new subdomain and verify count updates* | |
</details>
---
<div id="glossary"></div>
@ -991,154 +1160,6 @@
</details>
---
<div id="domains-data-products"></div>
## Domains & Data Products
<details open>
<summary>📄 <b>Domains.spec.ts</b> (26 tests, 45 scenarios)</summary>
> Source: [`src/main/resources/ui/playwright/e2e/Pages/Domains.spec.ts`](https://github.com/open-metadata/OpenMetadata/blob/main/openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/Domains.spec.ts)
### Domains
| # | Test Case | Description |
|---|-----------|-------------|
| 1 | **Domains** - Create domains and add assets | Create domains and add assets |
| | ↳ *Create domain* | |
| | ↳ *Add assets to domain* | |
| | ↳ *Delete domain using delete modal* | |
| 2 | **Domains** - Create DataProducts and add remove assets | Create DataProducts and add remove assets |
| | ↳ *Add assets to domain* | |
| | ↳ *Create DataProducts* | |
| | ↳ *Follow & Un-follow DataProducts* | |
| | ↳ *Verify empty assets message and Add Asset button* | |
| | ↳ *Add assets to DataProducts* | |
| | ↳ *Remove assets from DataProducts* | |
| 3 | **Domains** - Follow & Un-follow domain | Follow & Un-follow domain |
| 4 | **Domains** - Add, Update custom properties for data product | Add, Update custom properties for data product |
| | ↳ *Create DataProduct and custom properties for it* | |
| | ↳ *Set ${...} Custom Property* | |
| | ↳ *Update ${...} Custom Property* | |
| 5 | **Domains** - Switch domain from navbar and check domain query call wrap in quotes | Switch domain from navbar and check domain query call wrap in quotes |
| 6 | **Domains** - Rename domain | Rename domain |
| 7 | **Domains** - Follow/unfollow subdomain and create nested sub domain | Follow/unfollow subdomain and create nested sub domain |
| 8 | **Domains** - Should clear assets from data products after deletion of data product in Domain | Clear assets from data products after deletion of data product in Domain |
| | ↳ *Delete domain & recreate the same domain and data product* | |
| 9 | **Domains** - Should inherit owners and experts from parent domain | Inherit owners and experts from parent domain |
| 10 | **Domains** - Domain owner should able to edit description of domain | Domain owner should able to edit description of domain |
| 11 | **Domains** - Verify domain and subdomain asset count accuracy | Domain and subdomain asset count accuracy |
| | ↳ *Create domain and subdomain via API* | |
| | ↳ *Add assets to domain* | |
| | ↳ *Add assets to subdomain* | |
| | ↳ *Verify domain asset count matches displayed cards* | |
| | ↳ *Verify subdomain asset count matches displayed cards* | |
| 12 | **Domains** - Verify domain tags and glossary terms | Domain tags and glossary terms |
| 13 | **Domains** - Verify data product tags and glossary terms | Data product tags and glossary terms |
| 14 | **Domains** - Verify clicking All Domains sets active domain to default value | Clicking All Domains sets active domain to default value |
| 15 | **Domains** - Verify redirect path on data product delete | Redirect path on data product delete |
| 16 | **Domains** - Verify duplicate domain creation | Duplicate domain creation |
| 17 | **Domains** - Create domain custom property and verify value persistence | Create domain custom property and verify value persistence |
| | ↳ *Create custom property for domain entity* | |
| | ↳ *Navigate to domain and assign custom property value* | |
| | ↳ *Reload and verify custom property value persists* | |
| | ↳ *Cleanup custom property* | |
| 18 | **Domains** - Domain announcement create, edit & delete | Domain announcement create, edit & delete |
| 19 | **Domains** - Data Product announcement create, edit & delete | Data Product announcement create, edit & delete |
| 20 | **Domains** - should handle domain after description is deleted | Tests that verify UI handles entities with deleted descriptions gracefully. The issue occurs when: 1. An entity is created with a description 2. The description is later deleted/cleared via API patch 3. The API returns the entity without a description field (due to @JsonInclude(NON_NULL)) 4. UI should handle this gracefully instead of crashing |
| 21 | **Domains** - should handle data product after description is deleted | Handle data product after description is deleted |
### Domains Rbac
| # | Test Case | Description |
|---|-----------|-------------|
| 1 | **Domains Rbac** - Domain Rbac | Domain Rbac |
| | ↳ *Assign assets to domains* | |
| | ↳ *User with access to multiple domains* | |
### Data Consumer Domain Ownership
| # | Test Case | Description |
|---|-----------|-------------|
| 1 | **Data Consumer Domain Ownership** - Data consumer can manage domain as owner | Data consumer can manage domain as owner |
| | ↳ *Check domain management permissions for data consumer owner* | |
### Domain Access with hasDomain() Rule
| # | Test Case | Description |
|---|-----------|-------------|
| 1 | **Domain Access with hasDomain() Rule** - User with hasDomain() rule can access domain and subdomain assets | User with hasDomain() rule can access domain and subdomain assets |
| | ↳ *Verify user can access domain assets* | |
| | ↳ *Verify user can access subdomain assets* | |
### Domain Access with noDomain() Rule
| # | Test Case | Description |
|---|-----------|-------------|
| 1 | **Domain Access with noDomain() Rule** - User with noDomain() rule cannot access tables without domain | User with noDomain() rule cannot access tables without domain |
| | ↳ *Verify user can access domain-assigned table* | |
| | ↳ *Verify user gets permission error for table without domain* | |
### Domain Tree View Functionality
| # | Test Case | Description |
|---|-----------|-------------|
| 1 | **Domain Tree View Functionality** - should render the domain tree view with correct details | Render the domain tree view with correct details |
</details>
<details open>
<summary>📄 <b>DomainDataProductsWidgets.spec.ts</b> (6 tests, 6 scenarios)</summary>
> Source: [`src/main/resources/ui/playwright/e2e/Features/LandingPageWidgets/DomainDataProductsWidgets.spec.ts`](https://github.com/open-metadata/OpenMetadata/blob/main/openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/LandingPageWidgets/DomainDataProductsWidgets.spec.ts)
### Domain and Data Product Asset Counts
| # | Test Case | Description |
|---|-----------|-------------|
| 1 | **Domain and Data Product Asset Counts** - Assign Widgets | Assign Widgets |
| 2 | **Domain and Data Product Asset Counts** - Verify Widgets are having 0 count initially | Widgets are having 0 count initially |
| 3 | **Domain and Data Product Asset Counts** - Domain asset count should update when assets are added | Domain asset count should update when assets are added |
| 4 | **Domain and Data Product Asset Counts** - Data Product asset count should update when assets are added | Data Product asset count should update when assets are added |
| 5 | **Domain and Data Product Asset Counts** - Domain asset count should update when assets are removed | Domain asset count should update when assets are removed |
| 6 | **Domain and Data Product Asset Counts** - Data Product asset count should update when assets are removed | Data Product asset count should update when assets are removed |
</details>
<details open>
<summary>📄 <b>DomainPermissions.spec.ts</b> (2 tests, 2 scenarios)</summary>
> Source: [`src/main/resources/ui/playwright/e2e/Features/Permissions/DomainPermissions.spec.ts`](https://github.com/open-metadata/OpenMetadata/blob/main/openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Permissions/DomainPermissions.spec.ts)
### Standalone Tests
| # | Test Case | Description |
|---|-----------|-------------|
| 1 | Domain allow operations | Domain allow operations |
| 2 | Domain deny operations | Domain deny operations |
</details>
<details open>
<summary>📄 <b>SubDomainPagination.spec.ts</b> (1 tests, 4 scenarios)</summary>
> Source: [`src/main/resources/ui/playwright/e2e/Pages/SubDomainPagination.spec.ts`](https://github.com/open-metadata/OpenMetadata/blob/main/openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/SubDomainPagination.spec.ts)
### SubDomain Pagination
| # | Test Case | Description |
|---|-----------|-------------|
| 1 | **SubDomain Pagination** - Verify subdomain count and pagination functionality | Subdomain count and pagination functionality |
| | ↳ *Verify subdomain count in tab label* | |
| | ↳ *Navigate to subdomains tab and verify initial data load* | |
| | ↳ *Test pagination navigation* | |
| | ↳ *Create new subdomain and verify count updates* | |
</details>
---
<div id="tags"></div>

View File

@ -2,7 +2,7 @@
# Integration
> **1 Components** | **5 Files** | **52 Tests** | **55 Scenarios** 🚀
> **1 Components** | **6 Files** | **53 Tests** | **57 Scenarios** 🚀
## Table of Contents
- [Connectors](#connectors)
@ -141,6 +141,21 @@
</details>
<details open>
<summary>📄 <b>ApiCollection.spec.ts</b> (1 tests, 2 scenarios)</summary>
> Source: [`src/main/resources/ui/playwright/e2e/Flow/ApiCollection.spec.ts`](https://github.com/open-metadata/OpenMetadata/blob/main/openmetadata-ui/src/main/resources/ui/playwright/e2e/Flow/ApiCollection.spec.ts)
### API Collection Entity Special Test Cases
| # | Test Case | Description |
|---|-----------|-------------|
| 1 | **API Collection Entity Special Test Cases** - Verify Owner Propagation: owner should be propagated to the API Collection's API Endpoint | Owner Propagation: owner should be propagated to the API Collection's API Endpoint |
| | ↳ *Verify user Owner Propagation: owner should be propagated to the API Collection's API Endpoint* | |
| | ↳ *Verify team Owner Propagation: owner should be propagated to the API Collection's API Endpoint* | |
</details>
<details open>
<summary>📄 <b>ApiServiceRest.spec.ts</b> (1 tests, 1 scenarios)</summary>

View File

@ -2,7 +2,7 @@
# Platform
> **12 Components** | **69 Files** | **1246 Tests** | **1626 Scenarios** 🚀
> **12 Components** | **68 Files** | **1246 Tests** | **1628 Scenarios** 🚀
## Table of Contents
- [Other](#other)
@ -261,21 +261,6 @@
</details>
<details open>
<summary>📄 <b>ApiCollection.spec.ts</b> (1 tests, 2 scenarios)</summary>
> Source: [`src/main/resources/ui/playwright/e2e/Flow/ApiCollection.spec.ts`](https://github.com/open-metadata/OpenMetadata/blob/main/openmetadata-ui/src/main/resources/ui/playwright/e2e/Flow/ApiCollection.spec.ts)
### API Collection Entity Special Test Cases
| # | Test Case | Description |
|---|-----------|-------------|
| 1 | **API Collection Entity Special Test Cases** - Verify Owner Propagation: owner should be propagated to the API Collection's API Endpoint | Owner Propagation: owner should be propagated to the API Collection's API Endpoint |
| | ↳ *Verify user Owner Propagation: owner should be propagated to the API Collection's API Endpoint* | |
| | ↳ *Verify team Owner Propagation: owner should be propagated to the API Collection's API Endpoint* | |
</details>
<details open>
<summary>📄 <b>ApiDocs.spec.ts</b> (1 tests, 1 scenarios)</summary>
@ -2250,7 +2235,7 @@
## Personas & Customizations
<details open>
<summary>📄 <b>CustomizeDetailPage.spec.ts</b> (24 tests, 79 scenarios)</summary>
<summary>📄 <b>CustomizeDetailPage.spec.ts</b> (25 tests, 83 scenarios)</summary>
> Source: [`src/main/resources/ui/playwright/e2e/Features/CustomizeDetailPage.spec.ts`](https://github.com/open-metadata/OpenMetadata/blob/main/openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/CustomizeDetailPage.spec.ts)
@ -2340,25 +2325,30 @@
| | ↳ *should show all the tabs & widget as default when no customization is done* | |
| | ↳ *apply customization* | |
| | ↳ *Validate customization* | |
| 15 | **Persona customization** - Glossary - customization should work | Glossary - customization should work |
| 15 | **Persona customization** - Data Product - customization should work | Data Product - customization should work |
| | ↳ *pre-requisite* | |
| | ↳ *should show all the tabs & widget as default when no customization is done* | |
| | ↳ *apply customization* | |
| | ↳ *Validate customization* | |
| 16 | **Persona customization** - Glossary Term - customization should work | Glossary Term - customization should work |
| 16 | **Persona customization** - Glossary - customization should work | Glossary - customization should work |
| | ↳ *pre-requisite* | |
| | ↳ *should show all the tabs & widget as default when no customization is done* | |
| | ↳ *apply customization* | |
| | ↳ *Validate customization* | |
| 17 | **Persona customization** - Validate Glossary Term details page after customization of tabs | Validate Glossary Term details page after customization of tabs |
| 17 | **Persona customization** - Glossary Term - customization should work | Glossary Term - customization should work |
| | ↳ *pre-requisite* | |
| | ↳ *should show all the tabs & widget as default when no customization is done* | |
| | ↳ *apply customization* | |
| | ↳ *Validate customization* | |
| 18 | **Persona customization** - Validate Glossary Term details page after customization of tabs | Validate Glossary Term details page after customization of tabs |
| | ↳ *pre-requisite* | |
| | ↳ *apply customization* | |
| | ↳ *Validate customization* | |
| 18 | **Persona customization** - customize tab label should only render if it's customize by user | Customize tab label should only render if it's customize by user |
| 19 | **Persona customization** - customize tab label should only render if it's customize by user | Customize tab label should only render if it's customize by user |
| | ↳ *pre-requisite* | |
| | ↳ *apply tab label customization for Table* | |
| | ↳ *validate applied label change and language support for page* | |
| 19 | **Persona customization** - Domain - customize tab label should only render if it's customized by user | Domain - customize tab label should only render if it's customized by user |
| 20 | **Persona customization** - Domain - customize tab label should only render if it's customized by user | Domain - customize tab label should only render if it's customized by user |
| | ↳ *pre-requisite* | |
| | ↳ *apply tab label customization for Domain* | |
| | ↳ *validate applied label change for Domain Documentation tab* | |

View File

@ -7,35 +7,35 @@
| Metric | Count |
|--------|-------|
| **Components** | 30 |
| **Test Files** | 153 |
| **Test Cases** | 2361 |
| **Total Scenarios** | 3266 🚀 |
| **Test Files** | 154 |
| **Test Cases** | 2364 |
| **Total Scenarios** | 3277 🚀 |
---
## Governance
> **6 Components** | **669 Tests** | **1104 Scenarios**
> **6 Components** | **671 Tests** | **1111 Scenarios**
| Component | Files | Tests | Total Scenarios | Skipped |
|-----------|-------|-------|-----------------|---------|
| [Custom Properties](./Governance.md#custom-properties) | 5 | 293 | 304 | 0 |
| [Glossary](./Governance.md#glossary) | 20 | 212 | 249 | 0 |
| [Data Contracts](./Governance.md#data-contracts) | 2 | 86 | 429 | 0 |
| [Domains & Data Products](./Governance.md#domains-data-products) | 4 | 35 | 57 | 0 |
| [Domains & Data Products](./Governance.md#domains-data-products) | 5 | 37 | 64 | 0 |
| [Tags](./Governance.md#tags) | 7 | 34 | 49 | 0 |
| [Metrics](./Governance.md#metrics) | 3 | 9 | 16 | 0 |
## Platform
> **12 Components** | **1246 Tests** | **1626 Scenarios**
> **12 Components** | **1246 Tests** | **1628 Scenarios**
| Component | Files | Tests | Total Scenarios | Skipped |
|-----------|-------|-------|-----------------|---------|
| [Entities](./Platform.md#entities) | 15 | 927 | 1098 | 0 |
| [Users & Teams](./Platform.md#users-teams) | 9 | 80 | 100 | 0 |
| [Other](./Platform.md#other) | 18 | 66 | 77 | 0 |
| [Personas & Customizations](./Platform.md#personas-customizations) | 5 | 44 | 142 | 0 |
| [Other](./Platform.md#other) | 17 | 65 | 75 | 0 |
| [Personas & Customizations](./Platform.md#personas-customizations) | 5 | 45 | 146 | 0 |
| [Navigation](./Platform.md#navigation) | 4 | 38 | 38 | 0 |
| [Lineage (UI)](./Platform.md#lineage-ui-) | 3 | 32 | 87 | 0 |
| [RBAC](./Platform.md#rbac) | 4 | 19 | 34 | 0 |
@ -72,11 +72,11 @@
## Integration
> **1 Components** | **52 Tests** | **55 Scenarios**
> **1 Components** | **53 Tests** | **57 Scenarios**
| Component | Files | Tests | Total Scenarios | Skipped |
|-----------|-------|-------|-----------------|---------|
| [Connectors](./Integration.md#connectors) | 5 | 52 | 55 | 0 |
| [Connectors](./Integration.md#connectors) | 6 | 53 | 57 | 0 |
*Last updated: 2025-12-23*
*Last updated: 2025-12-26*

View File

@ -11,6 +11,7 @@
* limitations under the License.
*/
import { expect, Page, Response } from '@playwright/test';
import { DOMAIN_TAGS } from '../../../constant/config';
import { TableClass } from '../../../support/entity/TableClass';
import { getApiContext, redirectToHomePage } from '../../../utils/common';
import { waitForAllLoadersToDisappear } from '../../../utils/entity';
@ -21,7 +22,7 @@ import { test } from '../../fixtures/pages';
* Data Quality: Add Test Case (New Flow)
* @description E2E coverage for creating table/column test cases via the new flow, validating scheduler/pipeline behavior, bulk adding from entity page, and enforcing permissions for non-owner roles.
*/
test.describe('Add TestCase New Flow', () => {
test.describe('Add TestCase New Flow', { tag: DOMAIN_TAGS.OBSERVABILITY }, () => {
// Helper function to select table
const selectTable = async (page: Page, table: TableClass) => {
await page.click('[id="root\\/table"]');

View File

@ -62,7 +62,7 @@ export class TableClass extends EntityClass {
name: string;
displayName: string;
description: string;
columns: unknown[];
columns: TableColumn[];
tableType: string;
databaseSchema: string;
};
@ -310,9 +310,8 @@ export class TableClass extends EntityClass {
await visitEntityPage({
page,
searchTerm: searchTerm ?? this.entityResponseData?.['fullyQualifiedName'],
dataTestId: `${
this.entityResponseData.service.name ?? this.service.name
}-${this.entityResponseData.name ?? this.entity.name}`,
dataTestId: `${this.entityResponseData.service.name ?? this.service.name
}-${this.entityResponseData.name ?? this.entity.name}`,
});
}