feat: add comprehensive testing and error tracking for edit mode
Add robust testing framework to prevent regression of edit mode: - Comprehensive regression tests for JavaScript syntax validation - Build-time JavaScript validation tool with Node.js integration - Enhanced error tracking with detailed logging and recovery - Makefile integration for `make validate-js` command Features: - Validates JavaScript syntax in generated HTML templates - Detects common issues like broken string literals and brace escaping - Enhanced error reporting with timestamps and context - Automatic error recovery for graceful degradation - Build validation to catch syntax errors before deployment 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -659,18 +659,115 @@ class DocumentManager:
|
||||
// Define editor class first (if in edit mode)
|
||||
{editor_scripts if edit_mode else ''}
|
||||
|
||||
// Error reporting utility
|
||||
function reportEditModeError(errorMsg, technicalDetails) {{
|
||||
// Enhanced error reporting utility
|
||||
function reportEditModeError(errorMsg, technicalDetails, errorType = 'error') {{
|
||||
const statusDiv = document.getElementById('markitect-status');
|
||||
const errorDiv = document.getElementById('error-details');
|
||||
const errorText = document.getElementById('error-text');
|
||||
const statusMsg = document.getElementById('status-message');
|
||||
const browserInfo = document.getElementById('browser-info');
|
||||
|
||||
if (statusMsg) statusMsg.textContent = 'Edit mode unavailable - content displayed in read-only mode';
|
||||
// Log to console for debugging
|
||||
console.error('[MarkiTect Edit Mode Error]', errorMsg, technicalDetails);
|
||||
|
||||
// Create error report object
|
||||
const errorReport = {{
|
||||
timestamp: new Date().toISOString(),
|
||||
error: errorMsg,
|
||||
details: technicalDetails,
|
||||
type: errorType,
|
||||
userAgent: navigator.userAgent,
|
||||
url: window.location.href,
|
||||
markdownContent: typeof markdownContent !== 'undefined' ? markdownContent.length + ' chars' : 'unavailable'
|
||||
}};
|
||||
|
||||
// Store error for potential reporting
|
||||
if (!window.markitectErrors) window.markitectErrors = [];
|
||||
window.markitectErrors.push(errorReport);
|
||||
|
||||
// Update UI
|
||||
if (statusMsg) {{
|
||||
const statusText = errorType === 'warning'
|
||||
? 'Edit mode partially available - some features may not work'
|
||||
: 'Edit mode unavailable - content displayed in read-only mode';
|
||||
statusMsg.textContent = statusText;
|
||||
}}
|
||||
|
||||
if (errorDiv) errorDiv.style.display = 'block';
|
||||
if (errorText) errorText.textContent = errorMsg + (technicalDetails ? ' (' + technicalDetails + ')' : '');
|
||||
if (errorText) {{
|
||||
const fullError = errorMsg + (technicalDetails ? ' (' + technicalDetails + ')' : '');
|
||||
errorText.textContent = fullError;
|
||||
}}
|
||||
if (browserInfo) browserInfo.textContent = navigator.userAgent.split(' ').slice(-2).join(' ');
|
||||
|
||||
// Auto-hide warnings after 10 seconds
|
||||
if (errorType === 'warning' && errorDiv) {{
|
||||
setTimeout(() => {{
|
||||
errorDiv.style.display = 'none';
|
||||
}}, 10000);
|
||||
}}
|
||||
}}
|
||||
|
||||
// Enhanced error recovery utility
|
||||
function attemptErrorRecovery(error, context) {{
|
||||
console.warn('[MarkiTect] Attempting error recovery for:', context, error);
|
||||
|
||||
try {{
|
||||
// Try to ensure content is still visible
|
||||
const contentDiv = document.getElementById('markdown-content');
|
||||
if (contentDiv && !contentDiv.innerHTML.trim()) {{
|
||||
// Fallback content rendering
|
||||
const fallbackHtml = markdownContent
|
||||
.replace(/^# (.*$)/gim, '<h1>$1</h1>')
|
||||
.replace(/^## (.*$)/gim, '<h2>$1</h2>')
|
||||
.replace(/\\n\\n/g, '<br><br>')
|
||||
.replace(/\\n/g, '<br>');
|
||||
contentDiv.innerHTML = '<div style="white-space: pre-wrap;">' + fallbackHtml + '</div>';
|
||||
|
||||
reportEditModeError('Recovered with fallback rendering', 'Edit features disabled', 'warning');
|
||||
return true;
|
||||
}}
|
||||
}} catch (recoveryError) {{
|
||||
console.error('[MarkiTect] Recovery failed:', recoveryError);
|
||||
}}
|
||||
|
||||
return false;
|
||||
}}
|
||||
|
||||
// Validation utility for edit mode state
|
||||
function validateEditModeState() {{
|
||||
const issues = [];
|
||||
|
||||
// Check required elements
|
||||
if (!document.getElementById('markdown-content')) {{
|
||||
issues.push('Missing markdown-content container');
|
||||
}}
|
||||
|
||||
if (!document.getElementById('markitect-status')) {{
|
||||
issues.push('Missing status display');
|
||||
}}
|
||||
|
||||
// Check JavaScript dependencies
|
||||
if (typeof marked === 'undefined') {{
|
||||
issues.push('marked.js library not available');
|
||||
}}
|
||||
|
||||
if (typeof MARKITECT_EDIT_MODE === 'undefined') {{
|
||||
issues.push('Edit mode configuration missing');
|
||||
}}
|
||||
|
||||
// Check for MarkitectEditor
|
||||
if (typeof MarkitectEditor === 'undefined') {{
|
||||
issues.push('MarkitectEditor class not defined');
|
||||
}}
|
||||
|
||||
if (issues.length > 0) {{
|
||||
console.warn('[MarkiTect] Edit mode validation issues:', issues);
|
||||
reportEditModeError('Edit mode validation failed', issues.join(', '), 'warning');
|
||||
return false;
|
||||
}}
|
||||
|
||||
return true;
|
||||
}}
|
||||
|
||||
// Status update utility
|
||||
@@ -718,19 +815,44 @@ class DocumentManager:
|
||||
}}
|
||||
|
||||
// Step 2: Try to enhance with edit capabilities (if in edit mode)
|
||||
{'''if (typeof MARKITECT_EDIT_MODE !== 'undefined' && MARKITECT_EDIT_MODE) {
|
||||
{'''if (typeof MARKITECT_EDIT_MODE !== 'undefined' && MARKITECT_EDIT_MODE) {{
|
||||
updateStatus("Initializing edit capabilities...");
|
||||
try {
|
||||
|
||||
// Validate edit mode prerequisites
|
||||
if (!validateEditModeState()) {{
|
||||
if (!attemptErrorRecovery('validation failed', 'edit mode prerequisites')) {{
|
||||
return; // Stop here if recovery fails
|
||||
}}
|
||||
}}
|
||||
|
||||
try {{
|
||||
updateStatus("Creating editor instance...");
|
||||
markitectEditor = new MarkitectEditor();
|
||||
updateStatus("✓ Edit mode active - click any section to edit");
|
||||
console.log("✓ Edit mode initialized successfully");
|
||||
} catch (error) {
|
||||
|
||||
// Final validation check
|
||||
setTimeout(() => {{
|
||||
const sections = document.querySelectorAll('.markitect-section-editable');
|
||||
if (sections.length === 0) {{
|
||||
reportEditModeError('No editable sections found', 'Content may not be compatible with edit mode', 'warning');
|
||||
}} else {{
|
||||
console.log(`[MarkiTect] Found ${{sections.length}} editable sections`);
|
||||
}}
|
||||
}}, 1000);
|
||||
|
||||
}} catch (error) {{
|
||||
updateStatus("Edit mode failed to initialize", true);
|
||||
reportEditModeError("Edit mode initialization failed", error.message);
|
||||
console.error("Edit mode error:", error);
|
||||
}
|
||||
}''' if edit_mode else ''}
|
||||
|
||||
// Try error recovery
|
||||
if (attemptErrorRecovery(error, 'editor initialization')) {{
|
||||
reportEditModeError("Edit mode partially recovered", error.message, 'warning');
|
||||
}} else {{
|
||||
reportEditModeError("Edit mode initialization failed", error.message);
|
||||
}}
|
||||
}}
|
||||
}}''' if edit_mode else ''}
|
||||
}});
|
||||
|
||||
// Handle CDN loading errors
|
||||
|
||||
Reference in New Issue
Block a user