#!/usr/bin/env node /** * Real User Functionality Tests * * This test file validates the actual functionality that users experience, * not just internal API calls. It tests the complete user workflow. */ const RefactorTestRunner = require('./refactor-test-runner.js'); const runner = new RefactorTestRunner(); runner.describe('Real User Functionality Tests', () => { runner.it('should allow users to edit content and see changes in DOM', () => { // 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'); const { SectionManager } = sectionModule; const { DOMRenderer } = domModule; const { DebugPanel } = debugModule; const { DocumentControls } = controlsModule; // Setup DOM 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(); // Setup document controls documentControls.create(); // Create sections from test markdown const testMarkdown = `# Original Title\nOriginal content that should be editable.`; const sections = sectionManager.createSectionsFromMarkdown(testMarkdown); domRenderer.renderAllSections(sections); const firstSection = sections[0]; const sectionElement = container.querySelector(`[data-section-id="${firstSection.id}"]`); // Verify original content is rendered runner.expect(sectionElement.innerHTML).toContain('Original Title'); // Simulate user clicking on section const clickEvent = new Event('click', { bubbles: true }); sectionElement.dispatchEvent(clickEvent); // Verify editing state is active runner.expect(firstSection.isEditing()).toBeTruthy(); // Find the floating menu and edit controls const floatingMenu = document.querySelector('.ui-edit-floating-menu'); runner.expect(floatingMenu).toBeTruthy(); const textarea = floatingMenu.querySelector('textarea'); const acceptButton = Array.from(floatingMenu.querySelectorAll('button')).find(btn => btn.textContent.includes('Accept')); runner.expect(textarea).toBeTruthy(); runner.expect(acceptButton).toBeTruthy(); // Simulate user editing content const newContent = '# Updated Title\nCompletely new content added by user.'; textarea.value = newContent; // Simulate user clicking accept acceptButton.click(); // Verify section is no longer editing runner.expect(firstSection.isEditing()).toBeFalsy(); // Verify floating menu is gone const menuAfterAccept = document.querySelector('.ui-edit-floating-menu'); runner.expect(menuAfterAccept).toBeFalsy(); // CRITICAL TEST: Verify DOM was actually updated with new content const updatedElement = container.querySelector(`[data-section-id="${firstSection.id}"]`); runner.expect(updatedElement.innerHTML).toContain('Updated Title'); runner.expect(updatedElement.innerHTML).toContain('Completely new content'); runner.expect(updatedElement.innerHTML).not.toContain('Original Title'); // Cleanup document.body.removeChild(container); documentControls.destroy(); }); runner.it('should allow users to reset all changes', () => { // Setup similar to above const sectionModule = require('../core/section-manager.js'); const domModule = require('../components/dom-renderer.js'); const controlsModule = require('../components/document-controls.js'); const { SectionManager } = sectionModule; const { DOMRenderer } = domModule; const { DocumentControls } = controlsModule; const container = document.createElement('div'); container.innerHTML = '
'; document.body.appendChild(container); const sectionManager = new SectionManager(); const domRenderer = new DOMRenderer(sectionManager, container); const documentControls = new DocumentControls(); documentControls.create(); // Create and modify content const testMarkdown = `# Test Section\nOriginal content for reset test.`; const sections = sectionManager.createSectionsFromMarkdown(testMarkdown); domRenderer.renderAllSections(sections); const firstSection = sections[0]; // Make changes to the section sectionManager.startEditing(firstSection.id); sectionManager.updateContent(firstSection.id, '# Modified Title\nModified content.'); sectionManager.acceptChanges(firstSection.id); // Verify changes are applied let sectionElement = container.querySelector(`[data-section-id="${firstSection.id}"]`); runner.expect(sectionElement.innerHTML).toContain('Modified Title'); runner.expect(firstSection.hasChanges()).toBeTruthy(); // Test reset functionality const resetButton = documentControls.getButton('reset-all'); runner.expect(resetButton).toBeTruthy(); // Click reset button resetButton.click(); // Verify content is reset sectionElement = container.querySelector(`[data-section-id="${firstSection.id}"]`); runner.expect(sectionElement.innerHTML).toContain('Test Section'); runner.expect(sectionElement.innerHTML).not.toContain('Modified Title'); runner.expect(firstSection.hasChanges()).toBeFalsy(); // Cleanup document.body.removeChild(container); documentControls.destroy(); }); runner.it('should handle cancel operations correctly', () => { const sectionModule = require('../core/section-manager.js'); const domModule = require('../components/dom-renderer.js'); const { SectionManager } = sectionModule; const { DOMRenderer } = domModule; const container = document.createElement('div'); container.innerHTML = '
'; document.body.appendChild(container); const sectionManager = new SectionManager(); const domRenderer = new DOMRenderer(sectionManager, container); const testMarkdown = `# Cancel Test\nContent that should remain unchanged.`; const sections = sectionManager.createSectionsFromMarkdown(testMarkdown); domRenderer.renderAllSections(sections); const firstSection = sections[0]; const originalContent = firstSection.currentMarkdown; // Start editing const sectionElement = container.querySelector(`[data-section-id="${firstSection.id}"]`); sectionElement.click(); // Make changes but cancel them const floatingMenu = document.querySelector('.ui-edit-floating-menu'); const textarea = floatingMenu.querySelector('textarea'); const cancelButton = Array.from(floatingMenu.querySelectorAll('button')).find(btn => btn.textContent.includes('Cancel')); textarea.value = '# This should be cancelled\nThis content should not appear.'; cancelButton.click(); // Verify content is unchanged const unchangedElement = container.querySelector(`[data-section-id="${firstSection.id}"]`); runner.expect(unchangedElement.innerHTML).toContain('Cancel Test'); runner.expect(unchangedElement.innerHTML).not.toContain('This should be cancelled'); runner.expect(firstSection.currentMarkdown).toBe(originalContent); // Cleanup document.body.removeChild(container); }); runner.it('should validate the complete editing workflow', () => { // This test validates the entire user experience end-to-end 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'); const { SectionManager } = sectionModule; const { DOMRenderer } = domModule; const { DebugPanel } = debugModule; const { DocumentControls } = controlsModule; const container = document.createElement('div'); container.innerHTML = '
'; document.body.appendChild(container); const sectionManager = new SectionManager(); const domRenderer = new DOMRenderer(sectionManager, container); const debugPanel = new DebugPanel(); const documentControls = new DocumentControls(); documentControls.create(); // Multi-section document const testMarkdown = `# Document Title Introduction paragraph. ## Section A Content for section A. ## Section B Content for section B.`; const sections = sectionManager.createSectionsFromMarkdown(testMarkdown); domRenderer.renderAllSections(sections); // Verify all sections are rendered const renderedSections = container.querySelectorAll('.ui-edit-section'); runner.expect(renderedSections.length).toBe(sections.length); // Test editing multiple sections const firstSection = sections[0]; const secondSection = sections[2]; // Section A // Edit first section renderedSections[0].click(); let floatingMenu = document.querySelector('.ui-edit-floating-menu'); let textarea = floatingMenu.querySelector('textarea'); let acceptButton = Array.from(floatingMenu.querySelectorAll('button')).find(btn => btn.textContent.includes('Accept')); textarea.value = '# Updated Document Title\nUpdated introduction.'; acceptButton.click(); // Edit second section renderedSections[2].click(); floatingMenu = document.querySelector('.ui-edit-floating-menu'); textarea = floatingMenu.querySelector('textarea'); acceptButton = Array.from(floatingMenu.querySelectorAll('button')).find(btn => btn.textContent.includes('Accept')); textarea.value = '## Updated Section A\nCompletely new content for section A.'; acceptButton.click(); // Verify both sections were updated const updatedSections = container.querySelectorAll('.ui-edit-section'); runner.expect(updatedSections[0].innerHTML).toContain('Updated Document Title'); runner.expect(updatedSections[2].innerHTML).toContain('Updated Section A'); // Test reset restores all sections const resetButton = documentControls.getButton('reset-all'); resetButton.click(); const resetSections = container.querySelectorAll('.ui-edit-section'); runner.expect(resetSections[0].innerHTML).toContain('Document Title'); runner.expect(resetSections[0].innerHTML).not.toContain('Updated Document Title'); runner.expect(resetSections[2].innerHTML).toContain('Section A'); runner.expect(resetSections[2].innerHTML).not.toContain('Updated Section A'); // Cleanup document.body.removeChild(container); documentControls.destroy(); }); }); module.exports = runner; // Run tests if called directly if (require.main === module) { console.log('🧪 Running Real User Functionality Tests'); runner.run().then(() => { console.log('✅ Real user functionality tests completed'); console.log('These tests validate what users actually experience, not just internal APIs'); }); }