Files
ebaysnipeextension/test-error-handler-integration.html
Kenso Grimm 216a972fef chore: initialize project repository with core extension files
- Add .gitignore to exclude node_modules, dist, logs, and system files
- Add comprehensive project documentation including README, deployment guide, and development setup
- Add .kiro project specifications for amazon-product-bar-extension, appwrite-cloud-storage, appwrite-userid-repair, blacklist-feature, and enhanced-item-management
- Add .kiro steering documents for product, structure, styling, and tech guidelines
- Add VSCode settings configuration for consistent development environment
- Add manifest.json and babel/vite configuration for extension build setup
- Add complete source code implementation including AppWrite integration, storage managers, UI components, and services
- Add comprehensive test suite with Jest configuration and 30+ test files covering all major modules
- Add test HTML files for integration testing and validation
- Add coverage reports and build validation scripts
- Add AppWrite setup and repair documentation for database schema management
- Add migration guides and responsive accessibility implementation documentation
- Establish foundation for Amazon product bar extension with full feature set including blacklist management, enhanced item workflows, and real-time synchronization
2026-01-12 17:46:42 +01:00

394 lines
16 KiB
HTML

<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ErrorHandler Integration Test</title>
<style>
body {
font-family: Arial, sans-serif;
max-width: 800px;
margin: 0 auto;
padding: 20px;
background-color: #f5f5f5;
}
.test-section {
background: white;
padding: 20px;
margin: 20px 0;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.test-result {
padding: 10px;
margin: 10px 0;
border-radius: 4px;
}
.success {
background-color: #d4edda;
color: #155724;
border: 1px solid #c3e6cb;
}
.error {
background-color: #f8d7da;
color: #721c24;
border: 1px solid #f5c6cb;
}
.info {
background-color: #d1ecf1;
color: #0c5460;
border: 1px solid #bee5eb;
}
button {
background-color: #007acc;
color: white;
border: none;
padding: 10px 20px;
border-radius: 4px;
cursor: pointer;
margin: 5px;
}
button:hover {
background-color: #005a9e;
}
.log-entry {
font-family: monospace;
font-size: 12px;
background: #f8f9fa;
padding: 5px;
margin: 2px 0;
border-left: 3px solid #007acc;
}
</style>
</head>
<body>
<h1>ErrorHandler Integration Test</h1>
<p>Diese Seite testet die umfassende Fehlerbehandlung für Enhanced Item Management.</p>
<div class="test-section">
<h2>Error Classification Tests</h2>
<button onclick="testErrorClassification()">Test Error Classification</button>
<div id="classification-results"></div>
</div>
<div class="test-section">
<h2>Retry Logic Tests</h2>
<button onclick="testRetryLogic()">Test Retry Logic</button>
<div id="retry-results"></div>
</div>
<div class="test-section">
<h2>AI Service Fallback Tests</h2>
<button onclick="testAIFallback()">Test AI Fallback</button>
<div id="ai-fallback-results"></div>
</div>
<div class="test-section">
<h2>Extraction Fallback Tests</h2>
<button onclick="testExtractionFallback()">Test Extraction Fallback</button>
<div id="extraction-fallback-results"></div>
</div>
<div class="test-section">
<h2>Storage Error Handling Tests</h2>
<button onclick="testStorageErrorHandling()">Test Storage Error Handling</button>
<div id="storage-error-results"></div>
</div>
<div class="test-section">
<h2>User-Friendly Messages Tests</h2>
<button onclick="testUserFriendlyMessages()">Test User-Friendly Messages</button>
<div id="user-friendly-results"></div>
</div>
<div class="test-section">
<h2>Error Log</h2>
<button onclick="showErrorLog()">Show Recent Errors</button>
<button onclick="clearErrorLog()">Clear Error Log</button>
<div id="error-log"></div>
</div>
<script type="module">
import { ErrorHandler, errorHandler } from './src/ErrorHandler.js';
// Make available globally for testing
window.errorHandler = errorHandler;
window.ErrorHandler = ErrorHandler;
// Mock event bus for testing
window.amazonExtEventBus = {
emit: (event, data) => {
console.log('Event emitted:', event, data);
}
};
window.testErrorClassification = function() {
const results = document.getElementById('classification-results');
results.innerHTML = '';
const testCases = [
{ error: new Error('Network request failed'), expectedType: 'network' },
{ error: new Error('Invalid API key'), expectedType: 'api_key' },
{ error: new Error('Request timeout'), expectedType: 'timeout' },
{ error: new Error('Storage failed'), expectedType: 'storage' },
{ error: new Error('quota exceeded'), expectedType: 'quota' },
{ error: new Error('Validation failed'), expectedType: 'validation' },
{ error: new Error('Failed to extract title'), expectedType: 'extraction' },
{ error: new Error('Mistral AI unavailable'), expectedType: 'ai_service' },
{ error: new Error('Random unknown error'), expectedType: 'unknown' }
];
testCases.forEach((testCase, index) => {
try {
const processed = errorHandler.handleError(testCase.error, {
component: 'test',
operation: `classification_test_${index}`
});
const isCorrect = processed.type === testCase.expectedType;
const resultDiv = document.createElement('div');
resultDiv.className = `test-result ${isCorrect ? 'success' : 'error'}`;
resultDiv.innerHTML = `
<strong>Test ${index + 1}:</strong> "${testCase.error.message}"<br>
Expected: ${testCase.expectedType}, Got: ${processed.type}
${isCorrect ? '✓' : '✗'}
`;
results.appendChild(resultDiv);
} catch (error) {
const resultDiv = document.createElement('div');
resultDiv.className = 'test-result error';
resultDiv.innerHTML = `<strong>Test ${index + 1} Failed:</strong> ${error.message}`;
results.appendChild(resultDiv);
}
});
};
window.testRetryLogic = async function() {
const results = document.getElementById('retry-results');
results.innerHTML = '<div class="test-result info">Testing retry logic...</div>';
try {
// Test successful operation
let attemptCount = 0;
const successOperation = async () => {
attemptCount++;
return 'success';
};
const successResult = await errorHandler.executeWithRetry(successOperation, {
component: 'test',
operationName: 'success_test'
});
// Test retryable error
let retryAttemptCount = 0;
const retryableOperation = async () => {
retryAttemptCount++;
if (retryAttemptCount < 3) {
throw new Error('Network error');
}
return 'success after retries';
};
const retryResult = await errorHandler.executeWithRetry(retryableOperation, {
maxRetries: 3,
component: 'test',
operationName: 'retry_test'
});
// Test non-retryable error
const nonRetryableOperation = async () => {
throw new Error('Invalid API key');
};
const nonRetryResult = await errorHandler.executeWithRetry(nonRetryableOperation, {
maxRetries: 3,
component: 'test',
operationName: 'non_retry_test'
});
results.innerHTML = `
<div class="test-result success">
<strong>Success Test:</strong> ${successResult.success ? '✓' : '✗'}
(${successResult.attempts} attempt)
</div>
<div class="test-result success">
<strong>Retry Test:</strong> ${retryResult.success ? '✓' : '✗'}
(${retryResult.attempts} attempts)
</div>
<div class="test-result success">
<strong>Non-Retry Test:</strong> ${!nonRetryResult.success && nonRetryResult.attempts === 1 ? '✓' : '✗'}
(${nonRetryResult.attempts} attempt, correctly not retried)
</div>
`;
} catch (error) {
results.innerHTML = `<div class="test-result error">Retry test failed: ${error.message}</div>`;
}
};
window.testAIFallback = function() {
const results = document.getElementById('ai-fallback-results');
results.innerHTML = '';
const testCases = [
{ title: 'Samsung Galaxy S21 Ultra 5G Smartphone 128GB', description: 'Normal title' },
{ title: 'Very Long Product Title That Exceeds Fifty Characters And Should Be Shortened', description: 'Long title' },
{ title: '', description: 'Empty title' },
{ title: null, description: 'Null title' }
];
testCases.forEach((testCase, index) => {
try {
const fallback = errorHandler.handleAIServiceFallback(
testCase.title,
new Error('AI service unavailable')
);
const isValid = fallback.titleSuggestions && fallback.titleSuggestions.length === 3;
const resultDiv = document.createElement('div');
resultDiv.className = `test-result ${isValid ? 'success' : 'error'}`;
resultDiv.innerHTML = `
<strong>${testCase.description}:</strong> ${isValid ? '✓' : '✗'}<br>
Suggestions: ${fallback.titleSuggestions ? fallback.titleSuggestions.join(', ') : 'None'}
`;
results.appendChild(resultDiv);
} catch (error) {
const resultDiv = document.createElement('div');
resultDiv.className = 'test-result error';
resultDiv.innerHTML = `<strong>${testCase.description} Failed:</strong> ${error.message}`;
results.appendChild(resultDiv);
}
});
};
window.testExtractionFallback = function() {
const results = document.getElementById('extraction-fallback-results');
results.innerHTML = '';
const testUrl = 'https://amazon.de/dp/B08N5WRWNW';
const extractionError = new Error('Could not extract product data');
try {
const fallback = errorHandler.handleExtractionFallback(testUrl, extractionError);
const isValid = fallback.requiresManualInput &&
fallback.url === testUrl &&
fallback.fallbackData &&
fallback.fallbackData.currency === 'EUR';
results.innerHTML = `
<div class="test-result ${isValid ? 'success' : 'error'}">
<strong>Extraction Fallback:</strong> ${isValid ? '✓' : '✗'}<br>
Manual Input Required: ${fallback.requiresManualInput}<br>
URL Preserved: ${fallback.url === testUrl}<br>
Fallback Data: ${JSON.stringify(fallback.fallbackData)}
</div>
`;
} catch (error) {
results.innerHTML = `<div class="test-result error">Extraction fallback test failed: ${error.message}</div>`;
}
};
window.testStorageErrorHandling = function() {
const results = document.getElementById('storage-error-results');
results.innerHTML = '';
const testData = { id: 'test', title: 'Test Item', price: '29.99' };
const storageError = new Error('Storage quota exceeded');
try {
const result = errorHandler.handleStorageError(testData, storageError);
const isValid = !result.success &&
result.dataPreserved &&
result.preservedData &&
result.preservedData.id === testData.id;
results.innerHTML = `
<div class="test-result ${isValid ? 'success' : 'error'}">
<strong>Storage Error Handling:</strong> ${isValid ? '✓' : '✗'}<br>
Data Preserved: ${result.dataPreserved}<br>
Message: ${result.message}<br>
Preserved Data ID: ${result.preservedData ? result.preservedData.id : 'None'}
</div>
`;
} catch (error) {
results.innerHTML = `<div class="test-result error">Storage error test failed: ${error.message}</div>`;
}
};
window.testUserFriendlyMessages = function() {
const results = document.getElementById('user-friendly-results');
results.innerHTML = '';
const errorTypes = [
'network', 'api_key', 'timeout', 'storage', 'quota',
'validation', 'extraction', 'ai_service', 'unknown'
];
errorTypes.forEach(errorType => {
try {
const error = new Error(`Test ${errorType} error`);
const processed = errorHandler.handleError(error, { component: 'test' });
processed.type = errorType; // Force type for testing
const friendlyError = errorHandler.getUserFriendlyError(processed);
const isValid = friendlyError.title &&
friendlyError.message &&
friendlyError.action &&
typeof friendlyError.canRetry === 'boolean';
const resultDiv = document.createElement('div');
resultDiv.className = `test-result ${isValid ? 'success' : 'error'}`;
resultDiv.innerHTML = `
<strong>${errorType}:</strong> ${isValid ? '✓' : '✗'}<br>
Title: ${friendlyError.title}<br>
Message: ${friendlyError.message}<br>
Action: ${friendlyError.action}<br>
Can Retry: ${friendlyError.canRetry}
`;
results.appendChild(resultDiv);
} catch (error) {
const resultDiv = document.createElement('div');
resultDiv.className = 'test-result error';
resultDiv.innerHTML = `<strong>${errorType} Failed:</strong> ${error.message}`;
results.appendChild(resultDiv);
}
});
};
window.showErrorLog = function() {
const logDiv = document.getElementById('error-log');
const recentErrors = errorHandler.getRecentErrors(10);
if (recentErrors.length === 0) {
logDiv.innerHTML = '<div class="test-result info">No errors in log</div>';
return;
}
logDiv.innerHTML = '<h3>Recent Errors:</h3>';
recentErrors.forEach((error, index) => {
const logEntry = document.createElement('div');
logEntry.className = 'log-entry';
logEntry.innerHTML = `
<strong>${index + 1}.</strong> [${error.component}] ${error.operation}: ${error.originalMessage}<br>
<small>Type: ${error.type} | Time: ${new Date(error.timestamp).toLocaleString()}</small>
`;
logDiv.appendChild(logEntry);
});
};
window.clearErrorLog = function() {
errorHandler.clearErrorLog();
document.getElementById('error-log').innerHTML = '<div class="test-result success">Error log cleared</div>';
};
// Auto-run basic test on load
document.addEventListener('DOMContentLoaded', () => {
console.log('ErrorHandler Integration Test loaded');
console.log('ErrorHandler instance:', errorHandler);
});
</script>
</body>
</html>