mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2026-01-08 05:26:19 +00:00
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:
parent
dfd82688e8
commit
6dde0843b7
@ -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",
|
||||
|
||||
@ -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',
|
||||
};
|
||||
|
||||
@ -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
|
||||
};
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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)
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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>
|
||||
|
||||
|
||||
@ -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* | |
|
||||
|
||||
@ -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*
|
||||
|
||||
@ -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"]');
|
||||
|
||||
@ -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}`,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user