Publication IA: - 4 templates (magazine, brief, essay, simple) avec CSS riche - Rewrite IA (article/exercises/tutorial/reference/mixed) - Modération avec timeout 12s + fallback safe - Quotas publish_enhance par tier (basic=2, pro=15, business=100) - Détection contenu stale (hash) - Migration DB publishedContent/publishedTemplate/publishedSourceHash Fixes: - cheerio v1.2: Element -> AnyNode (domhandler), decodeEntities cast - _isShared ajouté au type Note (champ virtuel serveur) - callout colors PDF export: extraction fonction pure testable - admin/published: guard note.userId null - Cmd+S fonctionne en mode dialog (pas seulement fullPage) i18n: - 23 clés publish* traduites dans les 15 locales - Extension Web Clipper: 13 locales mise à jour Tests: - callout-colors.test.ts (6 tests) - note-visible-in-view.test.ts (5 tests) - entitlements.test.ts + byok-entitlements.test.ts: mock usageLog + unstubAllEnvs - 199/199 tests passent Tracker: user-stories.md sync avec sprint-status.yaml
79 lines
2.1 KiB
HTML
79 lines
2.1 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<title>Test Sidepanel</title>
|
|
<style>
|
|
body { font-family: sans-serif; padding: 20px; }
|
|
.error { color: red; }
|
|
.success { color: green; }
|
|
pre { background: #f5f5f5; padding: 10px; overflow-x: auto; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<h1>Test Extension Memento</h1>
|
|
<div id="results"></div>
|
|
|
|
<script>
|
|
const results = document.getElementById('results');
|
|
|
|
function log(message, type = 'info') {
|
|
const div = document.createElement('div');
|
|
div.className = type;
|
|
div.textContent = message;
|
|
results.appendChild(div);
|
|
}
|
|
|
|
function testFile(filename) {
|
|
return fetch(filename)
|
|
.then(response => {
|
|
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
|
return response.text();
|
|
})
|
|
.then(content => {
|
|
log(`✓ ${filename} chargé (${content.length} bytes)`, 'success');
|
|
return { filename, content };
|
|
})
|
|
.catch(error => {
|
|
log(`✗ ${filename}: ${error.message}`, 'error');
|
|
return { filename, error };
|
|
});
|
|
}
|
|
|
|
async function testSidepanelJS() {
|
|
const script = document.createElement('script');
|
|
script.src = 'sidepanel.js';
|
|
script.onerror = () => log('✗ sidepanel.js: Erreur de chargement', 'error');
|
|
script.onload = () => {
|
|
log('✓ sidepanel.js chargé', 'success');
|
|
// Check for CSP violations
|
|
if (typeof chrome !== 'undefined') {
|
|
log('✓ API chrome disponible', 'success');
|
|
} else {
|
|
log('✗ API chrome non disponible (normal hors extension)', 'error');
|
|
}
|
|
};
|
|
document.head.appendChild(script);
|
|
}
|
|
|
|
async function runTests() {
|
|
log('🧪 Début des tests...', 'info');
|
|
|
|
// Test file loading
|
|
await Promise.all([
|
|
testFile('sidepanel.html'),
|
|
testFile('sidepanel.js'),
|
|
testFile('content.js'),
|
|
testFile('background.js'),
|
|
testFile('manifest.json')
|
|
]);
|
|
|
|
// Test sidepanel.js execution
|
|
await testSidepanelJS();
|
|
}
|
|
|
|
runTests();
|
|
</script>
|
|
</body>
|
|
</html>
|