Grouped 100+ docs into categories: - architecture/ - System design, DBAL, component architecture - analysis/ - Status reports, assessments, migration analysis - guides/ - Quick references, how-tos, integration guides - implementation/ - Implementation details, migration guides - packages/ - Package-specific docs (forum, notifications, etc) - phases/ - Phase completion summaries and deliverables - testing/ - E2E tests, Playwright, test architecture - workflow/ - Workflow engine documentation Root level retains: README, ROADMAP, AGENTS, CONTRACT, CLAUDE, PROMPT Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
14 KiB
Declarative Testing Architecture for MetaBuilder
Status: DESIGN DOCUMENT - Ready for Implementation Date: January 21, 2026 Objective: Complete 100% data-driven architecture by making all tests declarative (Playwright, Storybook, Unit)
Executive Summary
MetaBuilder already achieves 95% data-driven architecture through declarative configuration. The final 5% missing is the testing layer. This document outlines how to make ALL testing declarative (not TypeScript) by consolidating Playwright E2E flows, Storybook component stories, and unit tests into the packages system as JSON definitions.
Current State:
- ✅ Playwright tests: Declarative JSON in
packages/*/playwright/tests.json(exists!) - ✅ Storybook stories: Declarative JSON in
packages/*/storybook/stories.json(exists!) - ❌ Unit tests: Still TypeScript
.spec.tsfiles (needs conversion!)
Proposed End State:
- ✅ Unit tests: Declarative JSON in
packages/*/unit-tests/tests.json(NEW!) - ✅ Centralized test runner that executes all three declaratively
- ✅ 100% data-driven architecture achieved
Current Testing Infrastructure
1. Playwright E2E Tests (ALREADY DECLARATIVE) ✅
Location: packages/*/playwright/tests.json
Example: /packages/ui_home/playwright/tests.json
{
"$schema": "https://metabuilder.dev/schemas/package-playwright.schema.json",
"package": "ui_home",
"tests": [
{
"name": "should load home page successfully",
"tags": ["@smoke", "@critical"],
"steps": [
{ "action": "navigate", "url": "/" },
{ "action": "waitForLoadState", "state": "domcontentloaded" },
{ "action": "expect", "selector": "body", "assertion": { "matcher": "toContainText", "expected": "MetaBuilder" } }
]
}
]
}
Runner: /e2e/json-runner/ - Loads and executes declarative tests
2. Storybook Stories (ALREADY DECLARATIVE) ✅
Location: packages/*/storybook/stories.json
Example: /packages/ui_home/storybook/stories.json
{
"$schema": "https://metabuilder.dev/schemas/package-storybook.schema.json",
"title": "Home Page Components",
"stories": [
{
"name": "HomePage",
"render": "home_ui",
"description": "Complete home page with all sections"
}
]
}
Runner: storybook/json-loader/ - Loads and renders declarative stories
3. Unit Tests (NOT YET DECLARATIVE) ❌
Current Location: e2e/**/*.spec.ts (TypeScript)
Problem:
- Tests live outside package system
- Written in TypeScript (not data)
- Cannot be managed as configuration
- Not discoverable by package system
Proposed Location: packages/*/unit-tests/tests.json (JSON)
Schema: Schema already exists at /schemas/package-schemas/tests_schema.json
Proposed Unit Test Declarative Format
Package Structure
packages/[packageId]/
├── unit-tests/
│ ├── tests.json [Declarative unit tests]
│ ├── fixtures.json [Test data/mocks]
│ └── README.md [Test documentation]
├── playwright/
│ ├── tests.json [E2E flows]
│ └── metadata.json [Configuration]
└── storybook/
├── stories.json [Component stories]
└── config.json [Configuration]
Unit Test JSON Format Example
{
"$schema": "https://metabuilder.dev/schemas/tests.schema.json",
"schemaVersion": "2.0.0",
"package": "ui_home",
"description": "Unit tests for Home Page components",
"imports": [
{
"from": "@testing-library/react",
"import": ["render", "screen", "fireEvent"]
},
{
"from": "@/components/home",
"import": ["HomePage", "HeroSection"]
}
],
"setup": {
"beforeEach": [
{
"type": "fixture",
"name": "clearMocks",
"config": {
"target": "localStorage"
}
}
]
},
"testSuites": [
{
"id": "hero-section",
"name": "HeroSection Component",
"tests": [
{
"id": "renders-title",
"name": "should render hero title",
"arrange": {
"component": "HeroSection",
"props": {
"title": "Build Anything, Visually",
"subtitle": "No code required."
}
},
"act": {
"render": true
},
"assert": [
{
"selector": ".hero-title",
"matcher": "toHaveTextContent",
"expected": "Build Anything"
},
{
"selector": ".hero-subtitle",
"matcher": "toBeVisible"
}
]
},
{
"id": "renders-cta-buttons",
"name": "should render call-to-action buttons",
"arrange": {
"component": "HeroSection",
"props": { "title": "Test", "subtitle": "Test" }
},
"act": { "render": true },
"assert": [
{
"role": "button",
"text": "Get Started",
"matcher": "toBeVisible"
},
{
"role": "button",
"text": "Watch Demo",
"matcher": "toBeVisible"
}
]
}
]
},
{
"id": "home-page",
"name": "HomePage Component",
"tests": [
{
"id": "renders-all-sections",
"name": "should render all page sections",
"arrange": {
"component": "HomePage"
},
"act": { "render": true },
"assert": [
{ "selector": ".hero-section", "matcher": "toBeInTheDocument" },
{ "selector": ".features-section", "matcher": "toBeInTheDocument" },
{ "selector": ".about-section", "matcher": "toBeInTheDocument" },
{ "selector": ".contact-section", "matcher": "toBeInTheDocument" }
]
}
]
}
]
}
Universal Test Runner
Centralized Test Execution
npm run test # Run all tests (all types)
npm run test:e2e # Run Playwright E2E tests
npm run test:stories # Validate Storybook stories
npm run test:unit # Run unit tests
# Filter by package
npm run test -- --package ui_home
npm run test -- --tag @smoke
npm run test -- --package admin --tag @critical
Test Runner Architecture
/test-runners/
├── runner.ts [Main orchestrator]
├── e2e/
│ └── playwright-runner.ts [Runs Playwright tests]
├── storybook/
│ └── story-runner.ts [Validates Storybook stories]
└── unit/
└── vitest-runner.ts [Runs unit tests]
Implementation Phases
Phase 1: Create Unit Test Declarative Format (WEEK 1)
Tasks:
- Finalize
tests_schema.json(already ~80% complete) - Create unit test format documentation
- Define AAA (Arrange-Act-Assert) pattern for JSON
- Create example unit-tests package
Deliverables:
- Complete JSON schema for unit tests
- 3-4 example unit test JSON files
- Runner implementation draft
Estimated Effort: 2-3 days
Phase 2: Create Test Runner (WEEK 1-2)
Tasks:
-
Build unified test runner that:
- Discovers tests across all packages
- Loads JSON test definitions
- Executes in correct order (unit → story → E2E)
- Generates consolidated report
-
Integrate with existing runners:
- Hook into Playwright runner
- Hook into Vitest runner
- Hook into Storybook generator
Deliverables:
- Unified test runner CLI
- Package discovery engine
- Test orchestration logic
Estimated Effort: 3-4 days
Phase 3: Migrate Existing Tests (WEEK 2-3)
Tasks:
- Convert 50 existing
.spec.tsfiles to JSON - Move tests into package structure
- Validate all conversions
- Run full test suite and verify passes
Deliverables:
- All existing tests migrated to JSON
- Test coverage verified
- 100% pass rate maintained
Estimated Effort: 4-5 days
Phase 4: Documentation & Training (WEEK 3)
Tasks:
- Write comprehensive guide for writing unit tests as JSON
- Create migration examples
- Document best practices
- Train team on new approach
Deliverables:
DECLARATIVE_UNIT_TESTS_GUIDE.md(1000+ words)- Video tutorial
- Code examples for common patterns
Estimated Effort: 2-3 days
Benefits of Declarative Testing
1. 100% Data-Driven Architecture
- Everything is configuration, not code
- Follows MetaBuilder's core principle
- Enables non-developers to write tests
2. Better Test Discovery
- All tests discoverable via package system
- Automatic test collection
- Test reports grouped by package
3. Easier Test Maintenance
- No code duplication
- Consistent patterns across all tests
- Version control friendly (JSON diffs)
4. AI-Friendly
- LLMs can easily generate test JSON
- Tests can be generated from requirements
- Automated test generation possible
5. Improved Traceability
- Tests map to components via package
- Clear requirements → tests → code lineage
- Easier coverage analysis
6. Better Test Organization
- Tests live with their components
- No scattered test files
- Natural grouping by feature
Example: Complete System Flows Test Package
New Package Structure
packages/system_flows/
├── unit-tests/
│ └── tests.json [User flow unit tests]
├── playwright/
│ ├── tests.json [E2E flows: public → login → admin]
│ └── metadata.json [Test metadata]
├── storybook/
│ └── stories.json [UI component stories]
└── package.json
Unit Test Example
{
"schemaVersion": "2.0.0",
"package": "system_flows",
"testSuites": [
{
"id": "permission-levels",
"name": "Permission Level Access Control",
"tests": [
{
"id": "level-0-public",
"name": "Level 0 (Public) should access homepage",
"arrange": {
"user": { "level": 0, "authenticated": false }
},
"act": {
"navigate": "/"
},
"assert": [
{ "selector": "body", "matcher": "toBeVisible" },
{ "text": "Sign In", "matcher": "toBeVisible" }
]
},
{
"id": "level-5-supergod",
"name": "Level 5 (Supergod) should access schema editor",
"arrange": {
"user": { "level": 5, "authenticated": true }
},
"act": {
"navigate": "/admin/schema-editor"
},
"assert": [
{ "selector": ".schema-editor", "matcher": "toBeInTheDocument" },
{ "text": "Create Entity", "matcher": "toBeVisible" }
]
}
]
}
]
}
Playwright E2E Example
{
"package": "system_flows",
"tests": [
{
"name": "Complete user flow: public → login → admin",
"tags": ["@critical", "@flow"],
"steps": [
{ "action": "navigate", "url": "/" },
{ "action": "expect", "text": "Build Anything", "assertion": { "matcher": "toBeVisible" } },
{ "action": "click", "role": "button", "text": "Sign In" },
{ "action": "fill", "label": "Username", "value": "admin" },
{ "action": "fill", "label": "Password", "value": "password" },
{ "action": "click", "role": "button", "text": "Login" },
{ "action": "waitForLoadState", "state": "networkidle" },
{ "action": "expect", "selector": ".admin-dashboard", "assertion": { "matcher": "toBeVisible" } },
{ "action": "click", "role": "link", "text": "Package Manager" },
{ "action": "expect", "text": "Installed Packages", "assertion": { "matcher": "toBeVisible" } }
]
}
]
}
Technical Roadmap
Required Changes
-
Schema Enhancement
- Finalize
tests_schema.jsonwith all AAA matchers - Add fixture definitions
- Add mock/spy support definitions
- Finalize
-
Runner Implementation
- Create
test-runners/unit-runner.tsto execute JSON tests - Update main test orchestrator
- Integrate with CI/CD pipeline
- Create
-
Package System Updates
- Add
unit-tests/as recognized entity type - Update package discovery to include unit tests
- Add metadata validation
- Add
-
Test Migration
- Script to help convert
.spec.ts→tests.json - Validation tool to ensure equivalence
- Coverage report generator
- Script to help convert
Questions for Implementation
-
Test Execution Environment
- Should JSON tests be compiled to Vitest at runtime?
- Or create dedicated JSON test executor?
- Recommendation: Runtime compilation for better error reporting
-
Fixture Management
- Where do mocked data/fixtures live?
- In
unit-tests/fixtures.json? - Or inline in test definitions?
- Recommendation: Both - inline for simple, separate for complex
-
Snapshot Testing
- How to handle snapshot updates in JSON format?
- Store snapshots separately with references?
- Recommendation: Use hash-based references to external snapshots
-
CI/CD Integration
- Run all tests in parallel or sequentially?
- Per-package test isolation?
- Recommendation: Parallel by package, sequential within package
Success Criteria
✅ All tests are declarative (JSON) ✅ No TypeScript test files (100% migrated) ✅ All existing tests pass (100% coverage maintained) ✅ Unified test runner works seamlessly ✅ Package discovery includes unit tests ✅ Documentation complete with examples ✅ Team trained on new approach ✅ CI/CD integrated successfully
Conclusion
This document outlines the final step to achieve 100% data-driven architecture in MetaBuilder by making unit tests declarative. The infrastructure is already in place (schemas exist, runners exist), requiring primarily:
- Schema finalization (~2 days)
- Runner implementation (~4 days)
- Test migration (~5 days)
- Documentation (~3 days)
Total Estimated Effort: 14 days (2 weeks) for full implementation
This positions MetaBuilder as the most data-driven full-stack system available - everything from UI components to security policies to tests is declarative configuration, not code.
Ready for review and implementation planning! 🚀