#!/usr/bin/env node /** * Test Text Editor Button Functionality * * Tests that accept, cancel, and reset buttons work properly for text sections * and follow the same color coding as image editor */ const { TestRunner } = require('./test_runner.js'); const runner = new TestRunner(); runner.describe('Text Editor Button Functionality Tests', () => { runner.it('should create text editor buttons with proper color coding', async () => { // Load editor delete require.cache[require.resolve('/home/worsch/markitect_project/markitect/static/editor.js')]; require('/home/worsch/markitect_project/markitect/static/editor.js'); if (global.DOMRenderer && global.SectionManager) { const container = document.createElement('div'); container.innerHTML = '
'; document.body.appendChild(container); const manager = new global.SectionManager(); const renderer = new global.DOMRenderer(manager, container); // Create text section const textMarkdown = '# Test Heading\n\nThis is test content.'; const sections = manager.createSectionsFromMarkdown(textMarkdown); const textSection = sections[0]; // Mock element const mockElement = document.createElement('div'); mockElement.setAttribute('data-section-id', textSection.id); renderer.findSectionElement = () => mockElement; // Show text editor renderer.showEditor(textSection.id, textSection.currentMarkdown); // Verify buttons exist with correct colors const acceptBtn = mockElement.querySelector('.ui-edit-button-accept'); const cancelBtn = mockElement.querySelector('.ui-edit-button-cancel'); const resetBtn = mockElement.querySelector('.ui-edit-button-reset'); runner.expect(acceptBtn).toBeTruthy(); runner.expect(cancelBtn).toBeTruthy(); runner.expect(resetBtn).toBeTruthy(); // Verify color coding matches image editor runner.expect(acceptBtn.style.background).toBe('rgb(40, 167, 69)'); // #28a745 runner.expect(cancelBtn.style.background).toBe('rgb(220, 53, 69)'); // #dc3545 runner.expect(resetBtn.style.background).toBe('rgb(253, 126, 20)'); // #fd7e14 // Cleanup document.body.removeChild(container); } }); runner.it('should handle accept button functionality', async () => { if (global.DOMRenderer && global.SectionManager) { const container = document.createElement('div'); container.innerHTML = '
'; document.body.appendChild(container); const manager = new global.SectionManager(); const renderer = new global.DOMRenderer(manager, container); const textMarkdown = '# Original Content'; const sections = manager.createSectionsFromMarkdown(textMarkdown); const textSection = sections[0]; const mockElement = document.createElement('div'); mockElement.setAttribute('data-section-id', textSection.id); renderer.findSectionElement = () => mockElement; // Start editing and modify content manager.startEditing(textSection.id); manager.updateContent(textSection.id, '# Modified Content'); renderer.showEditor(textSection.id, textSection.currentMarkdown); // Mock updateSectionContent to track calls let updatedContent = null; renderer.updateSectionContent = (sectionId, content) => { updatedContent = content; }; // Click accept button const acceptBtn = mockElement.querySelector('.ui-edit-button-accept'); acceptBtn.click(); // Verify changes were accepted and editor closed runner.expect(textSection.currentMarkdown).toBe('# Modified Content'); runner.expect(mockElement.querySelector('.ui-edit-overlay-container')).toBeFalsy(); // Cleanup document.body.removeChild(container); } }); runner.it('should handle cancel button functionality', async () => { if (global.DOMRenderer && global.SectionManager) { const container = document.createElement('div'); container.innerHTML = '
'; document.body.appendChild(container); const manager = new global.SectionManager(); const renderer = new global.DOMRenderer(manager, container); const originalMarkdown = '# Original Content'; const sections = manager.createSectionsFromMarkdown(originalMarkdown); const textSection = sections[0]; const mockElement = document.createElement('div'); mockElement.setAttribute('data-section-id', textSection.id); renderer.findSectionElement = () => mockElement; // Start editing and modify content manager.startEditing(textSection.id); manager.updateContent(textSection.id, '# Modified Content'); renderer.showEditor(textSection.id, textSection.currentMarkdown); // Click cancel button const cancelBtn = mockElement.querySelector('.ui-edit-button-cancel'); cancelBtn.click(); // Verify changes were cancelled and editor closed runner.expect(textSection.currentMarkdown).toBe(originalMarkdown); runner.expect(mockElement.querySelector('.ui-edit-overlay-container')).toBeFalsy(); // Cleanup document.body.removeChild(container); } }); runner.it('should handle reset button functionality', async () => { if (global.DOMRenderer && global.SectionManager) { const container = document.createElement('div'); container.innerHTML = '
'; document.body.appendChild(container); const manager = new global.SectionManager(); const renderer = new global.DOMRenderer(manager, container); const originalMarkdown = '# Original Content'; const sections = manager.createSectionsFromMarkdown(originalMarkdown); const textSection = sections[0]; const mockElement = document.createElement('div'); mockElement.setAttribute('data-section-id', textSection.id); renderer.findSectionElement = () => mockElement; // Make and accept changes to section manager.startEditing(textSection.id); manager.updateContent(textSection.id, '# Modified Content'); manager.acceptChanges(textSection.id); // Verify section has been modified runner.expect(textSection.currentMarkdown).toBe('# Modified Content'); renderer.showEditor(textSection.id, textSection.currentMarkdown); // Mock updateSectionContent to track calls let updatedContent = null; renderer.updateSectionContent = (sectionId, content) => { updatedContent = content; }; // Click reset button const resetBtn = mockElement.querySelector('.ui-edit-button-reset'); resetBtn.click(); // Verify section was reset to original content and editor closed runner.expect(textSection.currentMarkdown).toBe(originalMarkdown); runner.expect(updatedContent).toBe(originalMarkdown); runner.expect(mockElement.querySelector('.ui-edit-overlay-container')).toBeFalsy(); // Cleanup document.body.removeChild(container); } }); runner.it('should properly identify section ID from button clicks', async () => { if (global.DOMRenderer && global.SectionManager) { const container = document.createElement('div'); container.innerHTML = '
'; document.body.appendChild(container); const manager = new global.SectionManager(); const renderer = new global.DOMRenderer(manager, container); const textMarkdown = '# Test Content'; const sections = manager.createSectionsFromMarkdown(textMarkdown); const textSection = sections[0]; const mockElement = document.createElement('div'); mockElement.setAttribute('data-section-id', textSection.id); renderer.findSectionElement = () => mockElement; renderer.showEditor(textSection.id, textSection.currentMarkdown); // Test getCurrentEditingSectionId with each button const acceptBtn = mockElement.querySelector('.ui-edit-button-accept'); const cancelBtn = mockElement.querySelector('.ui-edit-button-cancel'); const resetBtn = mockElement.querySelector('.ui-edit-button-reset'); const acceptSectionId = renderer.getCurrentEditingSectionId(acceptBtn); const cancelSectionId = renderer.getCurrentEditingSectionId(cancelBtn); const resetSectionId = renderer.getCurrentEditingSectionId(resetBtn); runner.expect(acceptSectionId).toBe(textSection.id); runner.expect(cancelSectionId).toBe(textSection.id); runner.expect(resetSectionId).toBe(textSection.id); // Cleanup document.body.removeChild(container); } }); runner.it('should close editor UI when buttons are clicked', async () => { if (global.DOMRenderer && global.SectionManager) { const container = document.createElement('div'); container.innerHTML = '
'; document.body.appendChild(container); const manager = new global.SectionManager(); const renderer = new global.DOMRenderer(manager, container); const textMarkdown = '# Test Content'; const sections = manager.createSectionsFromMarkdown(textMarkdown); const textSection = sections[0]; const mockElement = document.createElement('div'); mockElement.setAttribute('data-section-id', textSection.id); renderer.findSectionElement = () => mockElement; // Test each button closes the editor ['accept', 'cancel', 'reset'].forEach((buttonType) => { renderer.showEditor(textSection.id, textSection.currentMarkdown); // Verify editor is open const overlayContainer = mockElement.querySelector('.ui-edit-overlay-container'); runner.expect(overlayContainer).toBeTruthy(); // Click the button const button = mockElement.querySelector(`.ui-edit-button-${buttonType}`); button.click(); // Verify editor is closed const overlayAfterClick = mockElement.querySelector('.ui-edit-overlay-container'); runner.expect(overlayAfterClick).toBeFalsy(); }); // Cleanup document.body.removeChild(container); } }); }); // Run the tests if (require.main === module) { console.log('🔤 Running Text Editor Button Functionality Tests'); runner.run().then(() => { const results = runner.results; const failed = results.filter(r => r.status === 'FAIL').length; if (failed > 0) { console.log(`❌ ${failed} test(s) failed - text editor buttons need attention`); } else { console.log('✅ All text editor button tests passed!'); } }); } module.exports = runner;