Complete the cleanup by moving the final 6 JavaScript development files (4 debug tools + 2 demo HTML pages) to history archive. Additional Files Moved: - debug_buttons.js: Button functionality debugging tool - debug_floating_menu.js: Floating menu structure inspection - e2e_tests.js: End-to-end test runner with custom framework - final_functionality_verification.js: Final verification script - demo_clean_editor.html: Clean section editor demonstration - test_dom_integration.html: DOM integration testing page Documentation Updates: - Updated history/javascript-dev-tests/README.md to document all 59 archived files - Added categorization for debug tools and demo pages - Complete project root directory cleanup achieved Project Status: - ✅ Main directory now clean of all development artifacts - ✅ All 59 JavaScript development files properly archived - ✅ Comprehensive documentation of archived functionality - ✅ 79 automated tests providing equivalent coverage 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
242 lines
9.3 KiB
JavaScript
Executable File
242 lines
9.3 KiB
JavaScript
Executable File
#!/usr/bin/env node
|
|
|
|
/**
|
|
* End-to-End Tests for HTML Editor
|
|
*
|
|
* Comprehensive test suite for section editing and image manipulation
|
|
*/
|
|
|
|
const fs = require('fs');
|
|
const { TestRunner, HTMLFileTester } = require('./test_runner.js');
|
|
|
|
const runner = new TestRunner();
|
|
|
|
async function runE2ETests(htmlFile) {
|
|
console.log('🎭 Running End-to-End Tests for HTML Editor');
|
|
|
|
let tester;
|
|
|
|
runner.describe('Section Detection and Creation', () => {
|
|
runner.it('should load and parse HTML successfully', async () => {
|
|
tester = new HTMLFileTester(htmlFile);
|
|
const loaded = await tester.load();
|
|
runner.expect(loaded || tester.html).toBeTruthy();
|
|
});
|
|
|
|
runner.it('should detect image sections correctly', async () => {
|
|
// Check if image sections are being created
|
|
const hasImageSection = tester.html.includes('section.isImage()');
|
|
runner.expect(hasImageSection).toBeTruthy();
|
|
});
|
|
|
|
runner.it('should have proper section IDs', async () => {
|
|
// Check for data-section-id attributes
|
|
runner.expect(tester.html.includes('data-section-id')).toBeTruthy();
|
|
});
|
|
});
|
|
|
|
runner.describe('JavaScript Functions Availability', () => {
|
|
runner.it('should have image editor dialog function', async () => {
|
|
runner.expect(tester.hasJavaScript('showImageEditor')).toBeTruthy();
|
|
});
|
|
|
|
runner.it('should have all image manipulation functions', async () => {
|
|
const imageFunctions = [
|
|
'replaceImage',
|
|
'resizeImage',
|
|
'addImageCaption',
|
|
'removeImage'
|
|
];
|
|
|
|
for (const func of imageFunctions) {
|
|
runner.expect(tester.hasJavaScript(func)).toBeTruthy();
|
|
}
|
|
});
|
|
|
|
runner.it('should have button creation function', async () => {
|
|
runner.expect(tester.hasJavaScript('createButton')).toBeTruthy();
|
|
});
|
|
|
|
runner.it('should have auto-resize functionality', async () => {
|
|
runner.expect(tester.hasJavaScript('setupAutoResize')).toBeTruthy();
|
|
});
|
|
});
|
|
|
|
runner.describe('DOM Structure Validation', () => {
|
|
runner.it('should have container element', async () => {
|
|
if (tester.document) {
|
|
const container = tester.getElement('#markdown-content');
|
|
runner.expect(container).toBeTruthy();
|
|
} else {
|
|
runner.expect(tester.hasElement('#markdown-content')).toBeTruthy();
|
|
}
|
|
});
|
|
|
|
runner.it('should create sections with proper classes', async () => {
|
|
// Check if setupSectionElement is being called
|
|
runner.expect(tester.hasJavaScript('setupSectionElement')).toBeTruthy();
|
|
runner.expect(tester.hasJavaScript('ui-edit-section')).toBeTruthy();
|
|
});
|
|
});
|
|
|
|
if (tester.document && tester.window) {
|
|
runner.describe('Interactive Testing (DOM Available)', () => {
|
|
runner.it('should have MarkitectEditor available globally', async () => {
|
|
const hasGlobalEditor = tester.window.MarkitectEditor !== undefined;
|
|
runner.expect(hasGlobalEditor).toBeTruthy();
|
|
});
|
|
|
|
runner.it('should have sections rendered in DOM', async () => {
|
|
if (tester.document) {
|
|
const sections = tester.document.querySelectorAll('[data-section-id]');
|
|
runner.expect(sections.length > 0).toBeTruthy();
|
|
}
|
|
});
|
|
|
|
runner.it('should have clickable sections', async () => {
|
|
const sections = tester.document.querySelectorAll('.ui-edit-section');
|
|
runner.expect(sections.length > 0).toBeTruthy();
|
|
});
|
|
|
|
runner.it('should detect image sections properly', async () => {
|
|
// Look for sections that contain image markdown
|
|
const allSections = tester.document.querySelectorAll('[data-section-id]');
|
|
let imageCount = 0;
|
|
|
|
for (const section of allSections) {
|
|
if (section.innerHTML.includes('<img') || section.innerHTML.includes('![')) {
|
|
imageCount++;
|
|
}
|
|
}
|
|
|
|
runner.expect(imageCount > 0).toBeTruthy();
|
|
});
|
|
|
|
runner.it('should have global editor controls', async () => {
|
|
// Wait a bit for elements to be created
|
|
await new Promise(resolve => setTimeout(resolve, 100));
|
|
|
|
const saveBtn = tester.document.getElementById('save-document');
|
|
const resetBtn = tester.document.getElementById('reset-all');
|
|
const statusBtn = tester.document.getElementById('show-status');
|
|
|
|
// At least one should exist (they're created dynamically)
|
|
const hasControls = saveBtn || resetBtn || statusBtn ||
|
|
tester.document.querySelector('[id*="save"]') ||
|
|
tester.document.querySelector('[id*="reset"]') ||
|
|
tester.document.querySelector('[id*="status"]');
|
|
|
|
runner.expect(hasControls).toBeTruthy();
|
|
});
|
|
});
|
|
|
|
runner.describe('Button Functionality Validation', () => {
|
|
runner.it('should create buttons with proper event handlers', async () => {
|
|
// Check if createButton function includes addEventListener
|
|
const createButtonCode = tester.html.match(/createButton\([\s\S]*?\{[\s\S]*?\}/);
|
|
if (createButtonCode) {
|
|
const hasEventListener = createButtonCode[0].includes('addEventListener');
|
|
runner.expect(hasEventListener).toBeTruthy();
|
|
}
|
|
});
|
|
|
|
runner.it('should bind image manipulation handlers correctly', async () => {
|
|
// Check if the image buttons are created with proper actions
|
|
const hasImageButtonSetup = tester.html.includes('replaceImage(sectionId)') ||
|
|
tester.html.includes('this.replaceImage') ||
|
|
tester.html.includes('() => this.replaceImage');
|
|
runner.expect(hasImageButtonSetup).toBeTruthy();
|
|
});
|
|
|
|
runner.it('should have proper button styling', async () => {
|
|
// Check if buttons have CSS styling
|
|
const hasButtonStyling = tester.html.includes('btn.style.cssText') ||
|
|
tester.html.includes('style.background') ||
|
|
tester.html.includes('ui-edit-image-btn');
|
|
runner.expect(hasButtonStyling).toBeTruthy();
|
|
});
|
|
});
|
|
}
|
|
|
|
await runner.run();
|
|
return runner.results;
|
|
}
|
|
|
|
// Debug information extractor
|
|
function extractDebugInfo(htmlFile) {
|
|
const html = fs.readFileSync(htmlFile, 'utf8');
|
|
|
|
console.log('\n🔍 Debug Information Analysis:');
|
|
console.log('━'.repeat(50));
|
|
|
|
// Count different types of functions
|
|
const functions = {
|
|
'Image Functions': ['replaceImage', 'resizeImage', 'addImageCaption', 'removeImage'],
|
|
'Editor Functions': ['showEditor', 'showImageEditor', 'hideEditor'],
|
|
'UI Functions': ['createButton', 'setupAutoResize', 'setupSectionElement'],
|
|
'Manager Functions': ['handleSectionClick', 'handleAccept', 'handleCancel']
|
|
};
|
|
|
|
for (const [category, funcList] of Object.entries(functions)) {
|
|
console.log(`\n📋 ${category}:`);
|
|
for (const func of funcList) {
|
|
const exists = html.includes(func);
|
|
console.log(` ${exists ? '✅' : '❌'} ${func}`);
|
|
}
|
|
}
|
|
|
|
// Check for common issues
|
|
console.log('\n🔧 Common Issues Check:');
|
|
const issues = [
|
|
{
|
|
name: 'Button Event Binding',
|
|
check: html.includes('addEventListener(\'click\'')
|
|
},
|
|
{
|
|
name: 'Arrow Function Binding',
|
|
check: html.includes('() => this.')
|
|
},
|
|
{
|
|
name: 'Method Context Binding',
|
|
check: html.includes('.bind(this)')
|
|
},
|
|
{
|
|
name: 'Image Editor Creation',
|
|
check: html.includes('ui-edit-image-editor-container')
|
|
}
|
|
];
|
|
|
|
for (const issue of issues) {
|
|
console.log(` ${issue.check ? '✅' : '❌'} ${issue.name}`);
|
|
}
|
|
}
|
|
|
|
// Main execution
|
|
if (require.main === module) {
|
|
const htmlFile = process.argv[2] || '/tmp/test_complete_functionality.html';
|
|
|
|
if (!fs.existsSync(htmlFile)) {
|
|
console.error(`❌ File not found: ${htmlFile}`);
|
|
process.exit(1);
|
|
}
|
|
|
|
// Extract debug information first
|
|
extractDebugInfo(htmlFile);
|
|
|
|
// Run e2e tests
|
|
runE2ETests(htmlFile).then(results => {
|
|
const passed = results.filter(r => r.status === 'PASS').length;
|
|
const failed = results.filter(r => r.status === 'FAIL').length;
|
|
|
|
console.log(`\n🎯 E2E Test Summary: ${passed} passed, ${failed} failed`);
|
|
|
|
if (failed > 0) {
|
|
console.log('\n🚨 Issues found - investigate button functionality');
|
|
} else {
|
|
console.log('\n✨ All tests passed - functionality should work correctly');
|
|
}
|
|
}).catch(error => {
|
|
console.error('❌ E2E test runner failed:', error);
|
|
process.exit(1);
|
|
});
|
|
} |