Added comprehensive plugin system for independent JavaScript UI development: **Plugin Infrastructure:** - Extended existing MarkiTect plugin system with RenderingEnginePlugin base class - Added RENDERING plugin type to PluginType enum - Created RenderingConfig for asset management and deployment - Implemented RenderingEngineManager for plugin discovery and lifecycle **TestDrive JSUI Plugin:** - Extracted JavaScript UI components to independent testdrive-jsui plugin - Created standalone development environment (no Python required) - Implemented compass-positioned control panels (NW, NE, E, SE) - Added clean JSON configuration interface for Python↔JavaScript data transfer **Asset Management:** - Development mode: serve assets directly from plugin source directory - Production mode: deploy to _markitect/plugins/[plugin-name]/ structure - Configurable asset URLs and deployment strategies - Support for external dependencies (CDN resources) **Standalone Development:** - testdrive-jsui/test.html for browser-based development - Package.json with npm scripts for development server - Complete separation of JavaScript development from Python environment - Hot reload and standard web development workflow **Integration Demo:** - demo_plugin_integration.py showcasing all plugin capabilities - Standalone, plugin discovery, production deployment examples - Asset URL generation for different deployment modes This enables JavaScript-first development while maintaining clean integration with the MarkiTect Python ecosystem. Developers can now work on UI components independently using standard web development tools and workflows. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
193 lines
6.4 KiB
HTML
193 lines
6.4 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>DocumentNavigator TDD Test Runner</title>
|
|
<style>
|
|
body {
|
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
|
max-width: 1000px;
|
|
margin: 0 auto;
|
|
padding: 2rem;
|
|
background-color: #f8f9fa;
|
|
}
|
|
.test-header {
|
|
background: white;
|
|
padding: 2rem;
|
|
border-radius: 8px;
|
|
margin-bottom: 2rem;
|
|
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
|
}
|
|
.test-output {
|
|
background: #1a1a1a;
|
|
color: #00ff00;
|
|
font-family: 'Courier New', monospace;
|
|
padding: 1rem;
|
|
border-radius: 8px;
|
|
margin-top: 1rem;
|
|
white-space: pre-wrap;
|
|
overflow-x: auto;
|
|
max-height: 400px;
|
|
}
|
|
.run-button {
|
|
background: #007bff;
|
|
color: white;
|
|
border: none;
|
|
padding: 12px 24px;
|
|
border-radius: 6px;
|
|
font-size: 16px;
|
|
cursor: pointer;
|
|
transition: background 0.2s;
|
|
}
|
|
.run-button:hover {
|
|
background: #0056b3;
|
|
}
|
|
.run-button:disabled {
|
|
background: #6c757d;
|
|
cursor: not-allowed;
|
|
}
|
|
.status {
|
|
margin-top: 1rem;
|
|
padding: 1rem;
|
|
border-radius: 6px;
|
|
font-weight: bold;
|
|
}
|
|
.status.running {
|
|
background: #fff3cd;
|
|
color: #856404;
|
|
}
|
|
.status.passed {
|
|
background: #d4edda;
|
|
color: #155724;
|
|
}
|
|
.status.failed {
|
|
background: #f8d7da;
|
|
color: #721c24;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="test-header">
|
|
<h1>📋 DocumentNavigator Widget TDD Test Suite</h1>
|
|
<p>
|
|
This test suite follows Test-Driven Development methodology to implement a Substack-style
|
|
floating document navigation widget. The tests define the expected behavior before
|
|
implementation begins.
|
|
</p>
|
|
|
|
<div>
|
|
<strong>Test Coverage:</strong>
|
|
<ul>
|
|
<li>✅ Widget class structure and inheritance</li>
|
|
<li>✅ Configuration and initialization</li>
|
|
<li>✅ DOM rendering and UI elements</li>
|
|
<li>✅ Heading extraction and hierarchy building</li>
|
|
<li>✅ Navigation functionality and smooth scrolling</li>
|
|
<li>✅ Expand/collapse behavior</li>
|
|
<li>✅ Scroll spy and active section detection</li>
|
|
<li>✅ Responsive behavior and auto-hide</li>
|
|
<li>✅ Keyboard navigation support</li>
|
|
<li>✅ Event emission and user interaction</li>
|
|
<li>✅ Edge cases and error handling</li>
|
|
</ul>
|
|
</div>
|
|
|
|
<button id="runTests" class="run-button">🧪 Run TDD Test Suite</button>
|
|
|
|
<div id="status" class="status" style="display: none;"></div>
|
|
</div>
|
|
|
|
<div id="testOutput" class="test-output" style="display: none;"></div>
|
|
|
|
<script type="module">
|
|
const runButton = document.getElementById('runTests');
|
|
const statusDiv = document.getElementById('status');
|
|
const outputDiv = document.getElementById('testOutput');
|
|
|
|
// Capture console output
|
|
const originalConsoleLog = console.log;
|
|
const originalConsoleError = console.error;
|
|
let capturedOutput = '';
|
|
|
|
function captureConsole() {
|
|
capturedOutput = '';
|
|
|
|
console.log = (...args) => {
|
|
capturedOutput += args.join(' ') + '\n';
|
|
originalConsoleLog(...args);
|
|
};
|
|
|
|
console.error = (...args) => {
|
|
capturedOutput += 'ERROR: ' + args.join(' ') + '\n';
|
|
originalConsoleError(...args);
|
|
};
|
|
}
|
|
|
|
function restoreConsole() {
|
|
console.log = originalConsoleLog;
|
|
console.error = originalConsoleError;
|
|
}
|
|
|
|
function updateStatus(message, type) {
|
|
statusDiv.textContent = message;
|
|
statusDiv.className = `status ${type}`;
|
|
statusDiv.style.display = 'block';
|
|
}
|
|
|
|
function showOutput() {
|
|
outputDiv.textContent = capturedOutput;
|
|
outputDiv.style.display = 'block';
|
|
}
|
|
|
|
runButton.addEventListener('click', async () => {
|
|
runButton.disabled = true;
|
|
updateStatus('🧪 Running tests...', 'running');
|
|
|
|
captureConsole();
|
|
|
|
try {
|
|
// Import and run tests
|
|
const { runner } = await import('./test-document-navigator.js');
|
|
|
|
console.log('Starting DocumentNavigator TDD Test Suite...\n');
|
|
console.log('Note: Tests are expected to FAIL initially (Red phase of TDD)');
|
|
console.log('We will implement functionality to make them pass (Green phase).\n');
|
|
|
|
await runner.run();
|
|
|
|
if (runner.results.failed === 0) {
|
|
updateStatus(`🎉 All ${runner.results.total} tests passed!`, 'passed');
|
|
} else {
|
|
updateStatus(`❌ ${runner.results.failed} of ${runner.results.total} tests failed (Expected in TDD Red phase)`, 'failed');
|
|
}
|
|
|
|
} catch (error) {
|
|
console.error('Test execution failed:', error);
|
|
updateStatus('💥 Test execution failed - this is expected in TDD Red phase', 'failed');
|
|
} finally {
|
|
restoreConsole();
|
|
showOutput();
|
|
runButton.disabled = false;
|
|
}
|
|
});
|
|
|
|
// Auto-run tests on page load for development
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
console.log('DocumentNavigator TDD Test Runner loaded');
|
|
console.log('Ready to run tests - click the button above');
|
|
});
|
|
</script>
|
|
|
|
<!-- Test content for heading extraction tests -->
|
|
<div style="display: none;" id="test-content">
|
|
<h1>Test Chapter 1</h1>
|
|
<p>Sample content for testing heading extraction.</p>
|
|
<h2>Section 1.1</h2>
|
|
<h3>Subsection 1.1.1</h3>
|
|
<p>More sample content.</p>
|
|
<h2>Section 1.2</h2>
|
|
<h1>Test Chapter 2</h1>
|
|
</div>
|
|
</body>
|
|
</html> |