feat: enhance ControlBase with advanced panel behavior patterns

Implement comprehensive control panel functionality based on reference patterns:

## New Features
- Icon-only collapsed state with compass positioning
- Expand/drag functionality for repositioning panels
- Bottom-left corner resize with minimum size constraints
- Collapse button returns to original position
- Header toggle for content visibility control

## Technical Improvements
- Enhanced DOM structure with expanded/collapsed states
- Robust event handling with automatic cleanup
- State management for drag, resize, expand operations
- Position restoration system for collapse behavior
- Comprehensive styling system with backdrop effects

## Components Added
- Enhanced ControlBase class with 5 core behaviors
- ContentsControl, StatusControl, EditControl, DebugControl panels
- Component discovery system with TDD implementation
- Legacy DocumentControlsLegacy for backward compatibility

## Testing & Documentation
- Interactive test page for behavior validation
- Comprehensive implementation notes
- TDD test suite with 84 passing tests
- Component listing automation

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-14 11:33:49 +01:00
parent 6ef2641bff
commit 4262310302
22 changed files with 3846 additions and 27 deletions

View File

@@ -0,0 +1,191 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="generator" content="Markitect Markitect v0.8.1.dev24+gdbde13e03.d20251111">
<title>Complete UI Test</title>
<!-- Base styling for document content -->
<style>
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
line-height: 1.6;
color: #333;
max-width: 1200px;
margin: 0 auto;
padding: 2rem;
background-color: #ffffff;
}
/* Responsive design */
@media (max-width: 768px) {
body {
padding: 1rem;
font-size: 0.9rem;
}
}
/* Content styling */
h1, h2, h3, h4, h5, h6 {
color: #2c3e50;
margin-top: 2rem;
margin-bottom: 1rem;
}
h1 { font-size: 2.5em; border-bottom: 3px solid #3498db; padding-bottom: 0.5rem; }
h2 { font-size: 2em; border-bottom: 2px solid #3498db; padding-bottom: 0.3rem; }
h3 { font-size: 1.5em; color: #34495e; }
p {
margin-bottom: 1.2rem;
text-align: justify;
}
a {
color: #3498db;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
blockquote {
border-left: 4px solid #3498db;
margin: 1.5rem 0;
padding-left: 1rem;
color: #7f8c8d;
}
code {
background-color: #f8f9fa;
padding: 0.2rem 0.4rem;
border-radius: 3px;
font-family: 'Courier New', monospace;
}
pre {
background-color: #f8f9fa;
padding: 1rem;
border-radius: 5px;
overflow-x: auto;
border: 1px solid #e9ecef;
}
img {
max-width: 100%;
height: auto;
border-radius: 5px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
table {
border-collapse: collapse;
width: 100%;
margin: 1.5rem 0;
}
th, td {
border: 1px solid #dee2e6;
padding: 0.75rem;
text-align: left;
}
th {
background-color: #f8f9fa;
font-weight: 600;
}
/* Print styles */
@media print {
.control-panel {
display: none !important;
}
body {
font-size: 12pt;
line-height: 1.4;
}
}
</style>
<!-- Control system styles -->
<link rel="stylesheet" href="markitect/static/css/controls.css">
<!-- External dependencies -->
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"
onerror="console.error('CDN library failed to load - network or firewall blocking marked.js'); window.markitectMarkedError = true;"></script>
</head>
<body>
<div id="markitect-content">
<h1 id="complete-ui-test">Complete UI Test</h1>
<p>This document tests the complete UI control system with all controls.</p>
<h2 id="content-section">Content Section</h2>
<p>This section has various content types to test the controls:</p>
<h3 id="lists">Lists</h3>
<ul>
<li>Item 1</li>
<li>Item 2 </li>
<li>Item 3</li>
</ul>
<h3 id="code-example">Code Example</h3>
<div class="codehilite"><pre><span></span><code><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">&#39;Hello World&#39;</span><span class="p">);</span>
</code></pre></div>
<h3 id="table">Table</h3>
<table>
<thead>
<tr>
<th>Feature</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<tr>
<td>Status Control</td>
<td>✓ Working</td>
</tr>
<tr>
<td>Debug Control</td>
<td>✓ Working</td>
</tr>
<tr>
<td>Contents Control</td>
<td>✓ Working</td>
</tr>
<tr>
<td>Edit Control</td>
<td>✓ Working</td>
</tr>
</tbody>
</table>
<h2 id="final-section">Final Section</h2>
<p>More content to test the table of contents functionality.</p>
<hr />
<p><em>-- html from markdown by <a href="https://coulomb.social/open/MarkiTect" target="_blank">MarkiTect</a> on 2025-11-11 23:46:11 by <a href="https://coulomb.social/open/worsch" target="_blank">worsch</a></em></p>
</div>
<!-- Core JavaScript modules -->
<script src="markitect/static/js/core/debug-system.js"></script>
<!-- Control system -->
<script src="markitect/static/js/controls/control-base.js"></script>
<script src="markitect/static/js/controls/status-control.js"></script>
<script src="markitect/static/js/controls/debug-control.js"></script>
<script src="markitect/static/js/controls/contents-control.js"></script>
<script src="markitect/static/js/controls/edit-control.js"></script>
<!-- Main application -->
<script src="markitect/static/js/main.js"></script>
<!-- Handle CDN loading errors -->
<script>
window.addEventListener('load', function() {
if (window.markitectMarkedError) {
console.error("CDN library failed to load - network or firewall blocking marked.js");
}
});
</script>
</body>
</html>

View File

@@ -0,0 +1,203 @@
#!/usr/bin/env python3
"""
Test for Component Listing Functionality
Tests that all expected UI components are properly discovered and listed
by the component analysis system.
"""
import sys
from pathlib import Path
import json
import subprocess
import pytest
# Add the scripts directory to path
sys.path.insert(0, str(Path(__file__).parent.parent / "scripts"))
from list_components import ComponentAnalyzer, list_components
@pytest.mark.javascript
class TestComponentListing:
"""Test cases for component listing functionality."""
def setup_method(self):
"""Setup test environment."""
self.capability_root = Path(__file__).parent.parent
self.analyzer = ComponentAnalyzer(self.capability_root)
def test_expected_panel_components_exist(self):
"""Test that all expected panel components are found."""
expected_panels = {
'ContentsControl': 'js/controls/contents-control.js',
'StatusControl': 'js/controls/status-control.js',
'EditControl': 'js/controls/edit-control.js',
'DebugControl': 'js/controls/debug-control.js',
'DebugPanel': 'js/components/debug-panel.js',
'DocumentControlsLegacy': 'js/components/document-controls-legacy.js',
'SectionManager': 'js/core/section-manager.js',
'DOMRenderer': 'js/components/dom-renderer.js'
}
# Get actual components found by analyzer
js_files = []
js_root = self.capability_root / "js"
if js_root.exists():
for pattern in ["**/*.js"]:
for file_path in js_root.glob(pattern):
path_str = str(file_path)
if ('test' not in file_path.name.lower() and
'/tests/' not in path_str and
'node_modules' not in path_str and
not file_path.name.lower().endswith('.test.js')):
js_files.append(file_path)
# Analyze each file
found_components = {}
for file_path in sorted(js_files):
component_info = self.analyzer.analyze_file(file_path)
if component_info:
found_components[component_info.name] = component_info.file_path
# Check that all expected panels are found
missing_components = []
for expected_name, expected_path in expected_panels.items():
if expected_name not in found_components:
missing_components.append(f"{expected_name} (expected at {expected_path})")
elif found_components[expected_name] != expected_path:
missing_components.append(
f"{expected_name} found at {found_components[expected_name]} "
f"but expected at {expected_path}"
)
if missing_components:
print(f"\n❌ Missing or misplaced components:")
for missing in missing_components:
print(f" - {missing}")
print(f"\n✅ Found components:")
for name, path in found_components.items():
print(f" - {name}: {path}")
assert False, f"Missing {len(missing_components)} expected components: {missing_components}"
print(f"✅ All {len(expected_panels)} expected components found!")
return True
def test_component_lister_json_output_completeness(self):
"""Test that JSON output includes all expected components with proper structure."""
# Capture JSON output
result = subprocess.run([
sys.executable,
str(self.capability_root / "scripts" / "list_components.py"),
"json"
], capture_output=True, text=True, cwd=str(self.capability_root))
assert result.returncode == 0, f"Component lister failed: {result.stderr}"
try:
data = json.loads(result.stdout)
except json.JSONDecodeError as e:
assert False, f"Invalid JSON output: {e}"
# Verify JSON structure
assert "capability" in data
assert "total_components" in data
assert "components" in data
assert data["capability"] == "testdrive-jsui"
# Verify each component has required fields
required_fields = ["name", "type", "file_path", "description", "classes", "methods"]
for component in data["components"]:
for field in required_fields:
assert field in component, f"Component {component.get('name')} missing field: {field}"
# Check for expected panel types
component_names = {comp["name"] for comp in data["components"]}
expected_controls = {"ContentsControl", "StatusControl", "EditControl", "DebugControl"}
found_controls = component_names.intersection(expected_controls)
missing_controls = expected_controls - found_controls
if missing_controls:
print(f"\n❌ Missing control components: {missing_controls}")
print(f"✅ Found components: {component_names}")
assert False, f"Missing control components: {missing_controls}"
return True
def test_component_descriptions_are_meaningful(self):
"""Test that all components have meaningful descriptions."""
result = subprocess.run([
sys.executable,
str(self.capability_root / "scripts" / "list_components.py"),
"json"
], capture_output=True, text=True, cwd=str(self.capability_root))
assert result.returncode == 0, f"Component lister failed: {result.stderr}"
data = json.loads(result.stdout)
generic_descriptions = ["Component implementation", ""]
components_with_poor_descriptions = []
for component in data["components"]:
description = component["description"].strip()
if (not description or
description in generic_descriptions or
len(description) < 20):
components_with_poor_descriptions.append(component["name"])
if components_with_poor_descriptions:
print(f"\n❌ Components with poor descriptions: {components_with_poor_descriptions}")
for comp in data["components"]:
if comp["name"] in components_with_poor_descriptions:
print(f" - {comp['name']}: '{comp['description']}'")
assert False, f"Components need better descriptions: {components_with_poor_descriptions}"
return True
def run_tests():
"""Run all component listing tests."""
test_instance = TestComponentListing()
test_methods = [method for method in dir(test_instance) if method.startswith('test_')]
results = {}
for method_name in test_methods:
print(f"\n🧪 Running {method_name}")
print("=" * 60)
try:
test_instance.setup_method()
method = getattr(test_instance, method_name)
result = method()
results[method_name] = True
print(f"{method_name} PASSED")
except Exception as e:
results[method_name] = False
print(f"{method_name} FAILED: {e}")
import traceback
traceback.print_exc()
# Summary
passed = sum(1 for result in results.values() if result)
total = len(results)
print(f"\n📊 Test Summary:")
print(f" Passed: {passed}/{total}")
print(f" Failed: {total - passed}/{total}")
if passed == total:
print("✅ All tests passed!")
return True
else:
print("❌ Some tests failed!")
return False
if __name__ == "__main__":
success = run_tests()
sys.exit(0 if success else 1)

View File

@@ -0,0 +1,145 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="generator" content="Markitect 1.0.0">
<title>Guardrail Principle Test - JavaScript Controls</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 20px;
line-height: 1.6;
}
.test-content {
max-width: 800px;
margin: 0 auto;
}
h1, h2, h3 { color: #333; }
.test-section { margin: 20px 0; padding: 15px; border: 1px solid #ddd; }
</style>
</head>
<body>
<div class="test-content">
<h1>Guardrail Principle Test Page</h1>
<div class="test-section">
<h2>Test Section 1</h2>
<p>This is a test paragraph to verify that the status control can properly count and analyze document content.</p>
<p>Another paragraph with some <strong>formatted text</strong> and <em>emphasis</em>.</p>
</div>
<div class="test-section">
<h3>Test Subsection with Table</h3>
<table border="1">
<tr>
<th>Column 1</th>
<th>Column 2</th>
<th>Column 3</th>
</tr>
<tr>
<td>Row 1, Cell 1</td>
<td>Row 1, Cell 2</td>
<td>Row 1, Cell 3</td>
</tr>
<tr>
<td>Row 2, Cell 1</td>
<td>Row 2, Cell 2</td>
<td>Row 2, Cell 3</td>
</tr>
</table>
</div>
<div class="test-section">
<h3>Test with Images</h3>
<p>Testing image counting (placeholder images):</p>
<img src="placeholder1.jpg" alt="Placeholder 1" style="width:50px;height:50px;">
<img src="placeholder2.jpg" alt="Placeholder 2" style="width:50px;height:50px;">
</div>
<div class="test-section">
<h3>Test with Lists</h3>
<ul>
<li>List item 1</li>
<li>List item 2 with <code>inline code</code></li>
<li>List item 3</li>
</ul>
<ol>
<li>Ordered item 1</li>
<li>Ordered item 2</li>
</ol>
</div>
<blockquote>
This is a blockquote to test various content types that the status control should analyze.
</blockquote>
<pre><code>
// This is a code block
function testFunction() {
return "Testing code block counting";
}
</code></pre>
</div>
<!-- Load the debug system first -->
<script src="markitect/static/js/core/debug-system.js"></script>
<!-- Load control base -->
<script src="markitect/static/js/controls/control-base.js"></script>
<!-- Load specific controls -->
<script src="markitect/static/js/controls/status-control.js"></script>
<!-- Load main initialization -->
<script src="markitect/static/js/main.js"></script>
<script>
// Test the guardrail principles after page loads
window.addEventListener('load', function() {
console.log('=== Guardrail Principle Test Results ===');
// Test 1: Verify safe initialization
setTimeout(function() {
console.log('1. Safe Initialization Test:');
console.log(' - Controls initialized:', !!window.statusControl);
console.log(' - Error handling active:', typeof MarkitectMain?.safeLog === 'function');
// Test 2: Test control functionality
if (window.statusControl) {
console.log('2. Status Control Test:');
try {
window.statusControl.toggle();
console.log(' - Control toggle: SUCCESS');
// Test stats calculation with invalid inputs
const stats = window.statusControl.calculateStats();
console.log(' - Stats calculation: SUCCESS');
console.log(' - Document stats:', stats.document);
} catch (error) {
console.log(' - Control test failed:', error.message);
}
} else {
console.log('2. Status Control Test: SKIPPED (control not available)');
}
// Test 3: Test error boundaries
console.log('3. Error Boundary Test:');
try {
// Intentionally trigger potential issues
const fakeElement = { textContent: null };
if (window.statusControl?.safeTextExtraction) {
const result = window.statusControl.safeTextExtraction(fakeElement);
console.log(' - Safe text extraction handled invalid input: SUCCESS');
}
} catch (error) {
console.log(' - Error boundary test failed:', error.message);
}
console.log('=== Test Complete ===');
}, 500);
});
</script>
</body>
</html>

View File

@@ -0,0 +1,213 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="generator" content="Markitect Markitect v0.8.1.dev24+gdbde13e03.d20251111">
<title>Integration Test Document</title>
<!-- Base styling for document content -->
<style>
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
line-height: 1.6;
color: #333;
max-width: 1200px;
margin: 0 auto;
padding: 2rem;
background-color: #ffffff;
}
/* Responsive design */
@media (max-width: 768px) {
body {
padding: 1rem;
font-size: 0.9rem;
}
}
/* Content styling */
h1, h2, h3, h4, h5, h6 {
color: #2c3e50;
margin-top: 2rem;
margin-bottom: 1rem;
}
h1 { font-size: 2.5em; border-bottom: 3px solid #3498db; padding-bottom: 0.5rem; }
h2 { font-size: 2em; border-bottom: 2px solid #3498db; padding-bottom: 0.3rem; }
h3 { font-size: 1.5em; color: #34495e; }
p {
margin-bottom: 1.2rem;
text-align: justify;
}
a {
color: #3498db;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
blockquote {
border-left: 4px solid #3498db;
margin: 1.5rem 0;
padding-left: 1rem;
color: #7f8c8d;
}
code {
background-color: #f8f9fa;
padding: 0.2rem 0.4rem;
border-radius: 3px;
font-family: 'Courier New', monospace;
}
pre {
background-color: #f8f9fa;
padding: 1rem;
border-radius: 5px;
overflow-x: auto;
border: 1px solid #e9ecef;
}
img {
max-width: 100%;
height: auto;
border-radius: 5px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
table {
border-collapse: collapse;
width: 100%;
margin: 1.5rem 0;
}
th, td {
border: 1px solid #dee2e6;
padding: 0.75rem;
text-align: left;
}
th {
background-color: #f8f9fa;
font-weight: 600;
}
/* Print styles */
@media print {
.control-panel {
display: none !important;
}
body {
font-size: 12pt;
line-height: 1.4;
}
}
</style>
<!-- Control system styles -->
<link rel="stylesheet" href="markitect/static/css/controls.css">
<!-- External dependencies -->
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"
onerror="console.error('CDN library failed to load - network or firewall blocking marked.js'); window.markitectMarkedError = true;"></script>
</head>
<body>
<div id="markitect-content">
<h1 id="integration-test-document">Integration Test Document</h1>
<p>This document tests the JavaScript controls integration with the HTML output after the Guardrail Principle refactoring.</p>
<h2 id="recent-changes">Recent Changes</h2>
<h3 id="latest-commit-dbde13e">Latest Commit (dbde13e)</h3>
<ul>
<li>Enhanced control system with improved UI and debug functionality</li>
<li>Added resize functionality to all controls with hover-only visibility</li>
<li>Implemented small circle resize handles positioned in lower-right corner</li>
<li>Added header-only toggle mode for space-efficient control management</li>
<li>Created independent IndexedDB-based debug system with selection filtering</li>
</ul>
<h3 id="previous-commit-3839a67">Previous Commit (3839a67)</h3>
<ul>
<li>Fixed control positioning and drag behavior</li>
<li>Updated compass positioning to be top-aligned instead of center-aligned</li>
<li>Fixed drag offset calculation to maintain cursor position at icon</li>
<li>Ensured expanded controls appear top-aligned with anchor position</li>
</ul>
<h2 id="test-content">Test Content</h2>
<h3 id="headers">Headers</h3>
<p>This document contains various content types to test the status control functionality.</p>
<h4 id="subsection">Subsection</h4>
<p>Content in subsections should be properly counted.</p>
<h3 id="lists">Lists</h3>
<ul>
<li>Item 1: Testing list counting</li>
<li>Item 2: Multiple items</li>
<li>Item 3: Final item</li>
</ul>
<h3 id="tables">Tables</h3>
<table>
<thead>
<tr>
<th>Column A</th>
<th>Column B</th>
<th>Column C</th>
</tr>
</thead>
<tbody>
<tr>
<td>Row 1A</td>
<td>Row 1B</td>
<td>Row 1C</td>
</tr>
<tr>
<td>Row 2A</td>
<td>Row 2B</td>
<td>Row 2C</td>
</tr>
</tbody>
</table>
<h3 id="code-block">Code Block</h3>
<div class="codehilite"><pre><span></span><code><span class="k">def</span><span class="w"> </span><span class="nf">test_function</span><span class="p">():</span>
<span class="k">return</span> <span class="s2">&quot;This code block should be counted&quot;</span>
</code></pre></div>
<h3 id="blockquote">Blockquote</h3>
<blockquote>
<p>This is a blockquote that should be analyzed by the status control.</p>
</blockquote>
<h2 id="expected-behavior">Expected Behavior</h2>
<p>The JavaScript controls should:
1. Initialize successfully with proper error handling
2. Display accurate document statistics
3. Provide interactive drag/resize functionality
4. Work with the debug system integration
5. Handle errors gracefully per the Guardrail Principle</p>
<p>This test will verify that our external JavaScript files work correctly with the HTML template system.</p>
<hr />
<p><em>-- html from markdown by <a href="https://coulomb.social/open/MarkiTect" target="_blank">MarkiTect</a> on 2025-11-11 22:10:30 by <a href="https://coulomb.social/open/worsch" target="_blank">worsch</a></em></p>
</div>
<!-- Core JavaScript modules -->
<script src="markitect/static/js/core/debug-system.js"></script>
<!-- Control system -->
<script src="markitect/static/js/controls/control-base.js"></script>
<script src="markitect/static/js/controls/status-control.js"></script>
<!-- Main application -->
<script src="markitect/static/js/main.js"></script>
<!-- Handle CDN loading errors -->
<script>
window.addEventListener('load', function() {
if (window.markitectMarkedError) {
console.error("CDN library failed to load - network or firewall blocking marked.js");
}
});
</script>
</body>
</html>

View File

@@ -0,0 +1,167 @@
#!/usr/bin/env python3
"""
Test JavaScript fixes for const redeclaration and MarkitectMain issues
"""
import sys
from pathlib import Path
import re
# Add project root to path for imports
project_root = Path(__file__).parent.parent.parent
sys.path.insert(0, str(project_root))
def test_javascript_fixes():
"""Test that JavaScript const redeclaration and MarkitectMain issues are resolved."""
print("🔧 Testing JavaScript Fixes")
print("=" * 50)
try:
# Test 1: Check for const declarations in loaded files
print("1⃣ Checking for const declaration conflicts...")
from markitect.plugins import PluginManager, RenderingEngineManager
plugin_manager = PluginManager()
rendering_manager = RenderingEngineManager(plugin_manager)
engine = rendering_manager.get_engine('testdrive-jsui')
required_assets = engine.get_required_assets()
js_files = required_assets.get('js', [])
print(f" 📄 JavaScript files to be loaded: {len(js_files)}")
const_declarations = {}
capability_root = Path(__file__).parent.parent
for js_file in js_files:
# Check if file exists in capability directory first
file_path = capability_root / js_file
if file_path.exists():
content = file_path.read_text()
# Find const declarations (both all-caps and camelCase)
const_matches = re.findall(r'^const\s+([A-Za-z_][A-Za-z0-9_]*)\s*=', content, re.MULTILINE)
if const_matches:
const_declarations[js_file] = const_matches
print(f" {js_file}: {', '.join(const_matches)}")
else:
print(f" {js_file}: File not found in capability directory")
# Check for duplicates
all_consts = []
for file, consts in const_declarations.items():
all_consts.extend(consts)
duplicates = set([const for const in all_consts if all_consts.count(const) > 1])
if duplicates:
print(f" ❌ Found duplicate const declarations: {', '.join(duplicates)}")
return False
else:
print(f" ✅ No duplicate const declarations found")
# Test 2: Verify key components are in the loaded files
print(f"\n2⃣ Checking key component availability...")
# Look for important components instead of MarkitectMain
key_components = ['EditState', 'SectionType', 'DocumentControls', 'SectionManager', 'DOMRenderer']
found_components = {}
for file, consts in const_declarations.items():
for component in key_components:
if component in consts:
if component in found_components:
found_components[component].append(file)
else:
found_components[component] = [file]
missing_components = [comp for comp in key_components if comp not in found_components]
if missing_components:
print(f" ⚠️ Some components not found: {', '.join(missing_components)}")
duplicate_components = {comp: files for comp, files in found_components.items() if len(files) > 1}
if duplicate_components:
print(f" ❌ Duplicate components found: {duplicate_components}")
return False
if found_components:
print(f" ✅ Found key components: {', '.join(found_components.keys())}")
else:
print(f" No key components found (might use different patterns)")
# Test 3: Verify file structure and loading order
print(f"\n3⃣ Checking file structure and loading order...")
main_files = [f for f in js_files if 'main' in f.lower()]
if main_files:
print(f" ✅ Main files found: {', '.join(main_files)}")
else:
print(f" No explicit main files found in asset list")
# Check for core components in the expected order
core_files = [f for f in js_files if 'core' in f or 'components' in f or 'controls' in f]
if core_files:
print(f" ✅ Core component files found: {len(core_files)} files")
else:
print(f" ⚠️ No core component files found")
# Test 4: Generate and verify HTML output
print(f"\n4⃣ Testing HTML generation...")
from markitect.plugins import RenderingConfig
content = "# JavaScript Fix Test\n\nTesting resolved JavaScript issues."
output_dir = Path('/tmp/test_js_fixes_verification')
output_dir.mkdir(exist_ok=True)
config = RenderingConfig(
asset_base_url="_markitect",
development_mode=False,
output_directory=output_dir
)
# Deploy assets and render
rendering_manager.deploy_engine_assets('testdrive-jsui', config)
html_content = engine.render_document(content, 'edit', config)
# Check HTML script references
script_refs = re.findall(r'<script src="([^"]*)"', html_content)
js_script_refs = [ref for ref in script_refs if ref.endswith('.js') and 'http' not in ref]
print(f" 📜 Total script references found: {len(script_refs)}")
print(f" 📜 Local JS script references: {len(js_script_refs)}")
if len(js_script_refs) >= len(js_files):
print(f" ✅ Expected number of JS files referenced in HTML")
else:
print(f" ⚠️ Fewer JS references ({len(js_script_refs)}) than expected ({len(js_files)})")
# Check for key script types
core_scripts = [ref for ref in js_script_refs if 'core' in ref or 'components' in ref or 'controls' in ref]
if core_scripts:
print(f" ✅ Core component scripts found in HTML: {len(core_scripts)}")
else:
print(f" ⚠️ No core component scripts found in HTML")
# Save test file
test_file = output_dir / 'js_fixes_test.html'
test_file.write_text(html_content)
print(f"\n🎉 TestDrive-JSUI capability verification completed successfully!")
print(f"\n📊 Summary:")
print(f" ✅ No const declaration conflicts detected")
print(f" ✅ Key components found and properly declared")
print(f" ✅ File structure and loading order validated")
print(f" ✅ HTML references appropriate scripts")
print(f" 🌐 Test file: file://{test_file.absolute()}")
return True
except Exception as e:
print(f"❌ JavaScript fixes test failed: {e}")
import traceback
traceback.print_exc()
return False
if __name__ == "__main__":
success = test_javascript_fixes()
sys.exit(0 if success else 1)