From 6dde0843b74ceb5bf546397dcb21cd518098577b Mon Sep 17 00:00:00 2001 From: Shailesh Parmar Date: Sat, 27 Dec 2025 19:05:07 +0530 Subject: [PATCH] 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 --- .../src/main/resources/ui/package.json | 2 +- .../ui/playwright/constant/config.ts | 8 + .../ui/playwright/doc-generator/generate.js | 77 +++-- .../ui/playwright/doc-generator/markdown.js | 35 +- .../doc-generator/playwright-loader.js | 15 +- .../ui/playwright/docs/Governance.md | 321 ++++++++++-------- .../ui/playwright/docs/Integration.md | 17 +- .../resources/ui/playwright/docs/Platform.md | 34 +- .../resources/ui/playwright/docs/README.md | 22 +- .../DataQuality/AddTestCaseNewFlow.spec.ts | 3 +- .../playwright/support/entity/TableClass.ts | 7 +- 11 files changed, 321 insertions(+), 220 deletions(-) diff --git a/openmetadata-ui/src/main/resources/ui/package.json b/openmetadata-ui/src/main/resources/ui/package.json index 58b53f94f7b..55ea77af258 100644 --- a/openmetadata-ui/src/main/resources/ui/package.json +++ b/openmetadata-ui/src/main/resources/ui/package.json @@ -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", diff --git a/openmetadata-ui/src/main/resources/ui/playwright/constant/config.ts b/openmetadata-ui/src/main/resources/ui/playwright/constant/config.ts index 558cbefca46..9cd4779f1b9 100644 --- a/openmetadata-ui/src/main/resources/ui/playwright/constant/config.ts +++ b/openmetadata-ui/src/main/resources/ui/playwright/constant/config.ts @@ -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', +}; diff --git a/openmetadata-ui/src/main/resources/ui/playwright/doc-generator/generate.js b/openmetadata-ui/src/main/resources/ui/playwright/doc-generator/generate.js index eee2431729f..3ef726b7b8f 100644 --- a/openmetadata-ui/src/main/resources/ui/playwright/doc-generator/generate.js +++ b/openmetadata-ui/src/main/resources/ui/playwright/doc-generator/generate.js @@ -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 +}; diff --git a/openmetadata-ui/src/main/resources/ui/playwright/doc-generator/markdown.js b/openmetadata-ui/src/main/resources/ui/playwright/doc-generator/markdown.js index afb549f1634..6343792d258 100644 --- a/openmetadata-ui/src/main/resources/ui/playwright/doc-generator/markdown.js +++ b/openmetadata-ui/src/main/resources/ui/playwright/doc-generator/markdown.js @@ -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; diff --git a/openmetadata-ui/src/main/resources/ui/playwright/doc-generator/playwright-loader.js b/openmetadata-ui/src/main/resources/ui/playwright/doc-generator/playwright-loader.js index b8e03eb2cba..6b6439e1e42 100644 --- a/openmetadata-ui/src/main/resources/ui/playwright/doc-generator/playwright-loader.js +++ b/openmetadata-ui/src/main/resources/ui/playwright/doc-generator/playwright-loader.js @@ -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) }; } diff --git a/openmetadata-ui/src/main/resources/ui/playwright/docs/Governance.md b/openmetadata-ui/src/main/resources/ui/playwright/docs/Governance.md index c863c49702b..7370e49469a 100644 --- a/openmetadata-ui/src/main/resources/ui/playwright/docs/Governance.md +++ b/openmetadata-ui/src/main/resources/ui/playwright/docs/Governance.md @@ -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 @@ +--- + +
+ +## Domains & Data Products + +
+šŸ“„ Domains.spec.ts (26 tests, 45 scenarios) + +> 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 | + +
+ +
+šŸ“„ DomainDataProductsWidgets.spec.ts (6 tests, 6 scenarios) + +> 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 | + +
+ +
+šŸ“„ DataProductPersonaCustomization.spec.ts (2 tests, 7 scenarios) + +> 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* | | + +
+ +
+šŸ“„ DomainPermissions.spec.ts (2 tests, 2 scenarios) + +> 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 | + +
+ +
+šŸ“„ SubDomainPagination.spec.ts (1 tests, 4 scenarios) + +> 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* | | + +
+ + ---
@@ -991,154 +1160,6 @@ ---- - -
- -## Domains & Data Products - -
-šŸ“„ Domains.spec.ts (26 tests, 45 scenarios) - -> 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 | - -
- -
-šŸ“„ DomainDataProductsWidgets.spec.ts (6 tests, 6 scenarios) - -> 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 | - -
- -
-šŸ“„ DomainPermissions.spec.ts (2 tests, 2 scenarios) - -> 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 | - -
- -
-šŸ“„ SubDomainPagination.spec.ts (1 tests, 4 scenarios) - -> 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* | | - -
- - ---
diff --git a/openmetadata-ui/src/main/resources/ui/playwright/docs/Integration.md b/openmetadata-ui/src/main/resources/ui/playwright/docs/Integration.md index d46df923be0..6c7124ff907 100644 --- a/openmetadata-ui/src/main/resources/ui/playwright/docs/Integration.md +++ b/openmetadata-ui/src/main/resources/ui/playwright/docs/Integration.md @@ -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 @@ +
+šŸ“„ ApiCollection.spec.ts (1 tests, 2 scenarios) + +> 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* | | + +
+
šŸ“„ ApiServiceRest.spec.ts (1 tests, 1 scenarios) diff --git a/openmetadata-ui/src/main/resources/ui/playwright/docs/Platform.md b/openmetadata-ui/src/main/resources/ui/playwright/docs/Platform.md index 43541103b5d..9af4bf4994d 100644 --- a/openmetadata-ui/src/main/resources/ui/playwright/docs/Platform.md +++ b/openmetadata-ui/src/main/resources/ui/playwright/docs/Platform.md @@ -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 @@
-
-šŸ“„ ApiCollection.spec.ts (1 tests, 2 scenarios) - -> 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* | | - -
-
šŸ“„ ApiDocs.spec.ts (1 tests, 1 scenarios) @@ -2250,7 +2235,7 @@ ## Personas & Customizations
-šŸ“„ CustomizeDetailPage.spec.ts (24 tests, 79 scenarios) +šŸ“„ CustomizeDetailPage.spec.ts (25 tests, 83 scenarios) > 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* | | diff --git a/openmetadata-ui/src/main/resources/ui/playwright/docs/README.md b/openmetadata-ui/src/main/resources/ui/playwright/docs/README.md index 0309e88428c..10a6412e09a 100644 --- a/openmetadata-ui/src/main/resources/ui/playwright/docs/README.md +++ b/openmetadata-ui/src/main/resources/ui/playwright/docs/README.md @@ -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* diff --git a/openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/DataQuality/AddTestCaseNewFlow.spec.ts b/openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/DataQuality/AddTestCaseNewFlow.spec.ts index 5148f7bf36c..3463b488708 100644 --- a/openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/DataQuality/AddTestCaseNewFlow.spec.ts +++ b/openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/DataQuality/AddTestCaseNewFlow.spec.ts @@ -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"]'); diff --git a/openmetadata-ui/src/main/resources/ui/playwright/support/entity/TableClass.ts b/openmetadata-ui/src/main/resources/ui/playwright/support/entity/TableClass.ts index f174ecab135..0e6c42d0b43 100644 --- a/openmetadata-ui/src/main/resources/ui/playwright/support/entity/TableClass.ts +++ b/openmetadata-ui/src/main/resources/ui/playwright/support/entity/TableClass.ts @@ -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}`, }); }