#!/usr/bin/env node /** * Full Integration Test * * Tests that all extracted components (SectionManager, DOMRenderer, * DebugPanel, DocumentControls) work together as a complete system. */ const RefactorTestRunner = require('./refactor-test-runner.js'); const runner = new RefactorTestRunner(); runner.describe('Full Component Integration Tests', () => { runner.it('should load all extracted components', () => { try { // Load all extracted components const sectionModule = require('../core/section-manager.js'); const domModule = require('../components/dom-renderer.js'); const debugModule = require('../components/debug-panel.js'); const controlsModule = require('../components/document-controls.js'); runner.expect(sectionModule.SectionManager).toBeTruthy(); runner.expect(domModule.DOMRenderer).toBeTruthy(); runner.expect(debugModule.DebugPanel).toBeTruthy(); runner.expect(controlsModule.DocumentControls).toBeTruthy(); // Set globals for other tests global.ExtractedSectionManager = sectionModule.SectionManager; global.ExtractedDOMRenderer = domModule.DOMRenderer; global.ExtractedDebugPanel = debugModule.DebugPanel; global.ExtractedDocumentControls = controlsModule.DocumentControls; } catch (error) { throw new Error(`Failed to load extracted components: ${error.message}`); } }); runner.it('should support complete document editing workflow with all components', () => { const SectionManager = global.ExtractedSectionManager; const DOMRenderer = global.ExtractedDOMRenderer; const DebugPanel = global.ExtractedDebugPanel; const DocumentControls = global.ExtractedDocumentControls; // Setup DOM container const container = document.createElement('div'); container.innerHTML = '
'; document.body.appendChild(container); // Create all components const sectionManager = new SectionManager(); const domRenderer = new DOMRenderer(sectionManager, container); const debugPanel = new DebugPanel(); const documentControls = new DocumentControls(); // Setup document controls documentControls.create(); // Wire up event handlers for debugging sectionManager.on('sections-created', (data) => { debugPanel.addMessage(`Created ${data.count} sections`, 'INFO'); }); sectionManager.on('edit-started', (data) => { debugPanel.addMessage(`Edit started for section: ${data.sectionId}`, 'DEBUG'); }); // Test workflow: Create document const testMarkdown = `# Document Title Introduction paragraph with some content. ## Section A Content for section A with details.  ### Subsection A.1 More detailed content here.`; // Create sections const sections = sectionManager.createSectionsFromMarkdown(testMarkdown); runner.expect(sections.length).toBe(4); // Render sections domRenderer.renderAllSections(sections); const renderedElements = container.querySelectorAll('.ui-edit-section'); runner.expect(renderedElements.length).toBe(sections.length); // Test editing workflow const firstSection = sections[0]; sectionManager.startEditing(firstSection.id); runner.expect(firstSection.isEditing()).toBeTruthy(); // Check debug messages were created runner.expect(debugPanel.getMessageCount()).toBe(2); // sections-created + edit-started // Test document controls functionality const controlPanel = documentControls.getControlPanel(); runner.expect(controlPanel).toBeTruthy(); runner.expect(document.getElementById('save-document')).toBeTruthy(); runner.expect(document.getElementById('toggle-debug')).toBeTruthy(); // Cleanup document.body.removeChild(container); documentControls.destroy(); }); runner.it('should support debug panel integration with document controls', () => { const DebugPanel = global.ExtractedDebugPanel; const DocumentControls = global.ExtractedDocumentControls; // Create components const debugPanel = new DebugPanel(); const documentControls = new DocumentControls(); // Setup document controls documentControls.create(); // Setup debug panel toggle handler const handlers = { 'toggle-debug': () => debugPanel.toggle() }; documentControls.setEventHandlers(handlers); // Test debug toggle functionality const debugButton = documentControls.getButton('toggle-debug'); runner.expect(debugButton).toBeTruthy(); // Add some debug messages debugPanel.addMessage('Test message 1', 'INFO'); debugPanel.addMessage('Test message 2', 'ERROR'); // Simulate button click to show debug panel debugButton.click(); runner.expect(debugPanel.isActive).toBeTruthy(); // Simulate button click to hide debug panel debugButton.click(); runner.expect(debugPanel.isActive).toBeFalsy(); // Cleanup documentControls.destroy(); }); runner.it('should support event-driven communication between all components', () => { const SectionManager = global.ExtractedSectionManager; const DOMRenderer = global.ExtractedDOMRenderer; const DebugPanel = global.ExtractedDebugPanel; const DocumentControls = global.ExtractedDocumentControls; // Setup container const container = document.createElement('div'); container.innerHTML = ''; document.body.appendChild(container); // Create components const sectionManager = new SectionManager(); const domRenderer = new DOMRenderer(sectionManager, container); const debugPanel = new DebugPanel(); const documentControls = new DocumentControls(); documentControls.create(); // Setup comprehensive event handling let eventLog = []; sectionManager.on('sections-created', (data) => { eventLog.push(`sections-created: ${data.count} sections`); debugPanel.addMessage(`Sections created: ${data.count}`, 'INFO'); }); sectionManager.on('edit-started', (data) => { eventLog.push(`edit-started: ${data.sectionId}`); debugPanel.addMessage(`Edit started: ${data.sectionId}`, 'DEBUG'); }); sectionManager.on('changes-accepted', (data) => { eventLog.push(`changes-accepted: ${data.sectionId}`); debugPanel.addMessage(`Changes accepted: ${data.sectionId}`, 'SUCCESS'); }); // Test complete workflow const testMarkdown = '# Test\nContent for testing'; const sections = sectionManager.createSectionsFromMarkdown(testMarkdown); domRenderer.renderAllSections(sections); // Start editing sectionManager.startEditing(sections[0].id); sectionManager.updateContent(sections[0].id, '# Updated Test\nUpdated content'); sectionManager.acceptChanges(sections[0].id); // Verify events were logged runner.expect(eventLog.length).toBe(3); runner.expect(eventLog[0]).toContain('sections-created'); runner.expect(eventLog[1]).toContain('edit-started'); runner.expect(eventLog[2]).toContain('changes-accepted'); // Verify debug messages were created runner.expect(debugPanel.getMessageCount()).toBe(3); // Test document controls status update const status = sectionManager.getDocumentStatus(); documentControls.updateStatus(status); runner.expect(documentControls.lastStatus).toBeTruthy(); // Cleanup document.body.removeChild(container); documentControls.destroy(); }); runner.it('should handle error scenarios gracefully across components', () => { const SectionManager = global.ExtractedSectionManager; const DOMRenderer = global.ExtractedDOMRenderer; const DebugPanel = global.ExtractedDebugPanel; const DocumentControls = global.ExtractedDocumentControls; // Test component creation without proper DOM setup const debugPanel = new DebugPanel(); const documentControls = new DocumentControls(); // These should not throw errors try { debugPanel.toggle(); // No DOM elements debugPanel.update(); // No DOM elements documentControls.show(); // No control panel created yet documentControls.hide(); // No control panel created yet runner.expect(true).toBeTruthy(); // If we get here, no errors were thrown } catch (error) { throw new Error(`Components should handle missing DOM gracefully: ${error.message}`); } // Test section manager with invalid input const sectionManager = new SectionManager(); const sections = sectionManager.createSectionsFromMarkdown(''); runner.expect(sections.length).toBe(0); // Test DOM renderer with invalid container try { const invalidRenderer = new DOMRenderer(sectionManager, null); runner.expect(invalidRenderer.container).toBeFalsy(); } catch (error) { // This is acceptable - constructor might validate input runner.expect(typeof error.message === 'string').toBeTruthy(); } }); runner.it('should support scalable architecture with component lifecycle', () => { const SectionManager = global.ExtractedSectionManager; const DOMRenderer = global.ExtractedDOMRenderer; const DebugPanel = global.ExtractedDebugPanel; const DocumentControls = global.ExtractedDocumentControls; // Test multiple instances const sectionManager1 = new SectionManager(); const sectionManager2 = new SectionManager(); const debugPanel1 = new DebugPanel(); const debugPanel2 = new DebugPanel(); // Each should be independent debugPanel1.addMessage('Message from panel 1', 'INFO'); debugPanel2.addMessage('Message from panel 2', 'ERROR'); runner.expect(debugPanel1.getMessageCount()).toBe(1); runner.expect(debugPanel2.getMessageCount()).toBe(1); // Test section managers are independent const sections1 = sectionManager1.createSectionsFromMarkdown('# Document 1'); const sections2 = sectionManager2.createSectionsFromMarkdown('# Document 2'); runner.expect(sections1.length).toBe(1); runner.expect(sections2.length).toBe(1); runner.expect(sections1[0]).toBeTruthy(); runner.expect(sections2[0]).toBeTruthy(); // IDs should be different (each section gets unique ID) const id1 = sections1[0].id; const id2 = sections2[0].id; runner.expect(id1 !== id2).toBeTruthy(); // Test document controls lifecycle const controls1 = new DocumentControls(); const controls2 = new DocumentControls(); controls1.create(); runner.expect(document.getElementById('markitect-global-controls')).toBeTruthy(); controls2.create(); // Should replace the first one runner.expect(document.getElementById('markitect-global-controls')).toBeTruthy(); controls2.destroy(); runner.expect(document.getElementById('markitect-global-controls')).toBeFalsy(); }); }); module.exports = runner; // Run tests if called directly if (require.main === module) { console.log('🧪 Running Full Component Integration Tests'); runner.run().then(() => { console.log('✅ Full integration tests completed'); }); }