Update dashboard, kb, memory +4 more (+28 ~18 -1)

This commit is contained in:
Echo
2026-02-06 14:25:10 +00:00
parent 7f64d5054a
commit 19d178268a
6767 changed files with 1346472 additions and 1282 deletions

271
test-mobile-files.js Normal file
View File

@@ -0,0 +1,271 @@
const puppeteer = require('puppeteer');
const fs = require('fs');
const testFiles = [
{ name: 'AGENTS.md', status: 'M', expectPreview: true, expectPDF: true, expectGitDiff: true },
{ name: 'FEATURE_PDF_DOWNLOAD.md', status: '??', expectPreview: true, expectPDF: true, expectGitDiff: false },
{ name: 'TOOLS.md', status: 'M', expectPreview: true, expectPDF: true, expectGitDiff: true },
{ name: 'dashboard/api.py', status: 'M', expectPreview: false, expectPDF: false, expectGitDiff: true },
{ name: 'memory/2026-02-05.md', status: '??', expectPreview: true, expectPDF: true, expectGitDiff: false }
];
(async () => {
const browser = await puppeteer.launch({
headless: true,
args: ['--no-sandbox', '--disable-setuid-sandbox']
});
const page = await browser.newPage();
await page.setViewport({ width: 375, height: 667 });
const results = [];
const consoleErrors = [];
// Capture console errors
page.on('console', msg => {
if (msg.type() === 'error') {
consoleErrors.push(`[${msg.type()}] ${msg.text()}`);
}
});
page.on('pageerror', error => {
consoleErrors.push(`[pageerror] ${error.message}`);
});
for (const file of testFiles) {
console.log(`\n========================================`);
console.log(`Testing: ${file.name} (${file.status})`);
console.log(`========================================`);
try {
// Navigate to the file
await page.goto(`http://localhost:8000/files.html#${file.name}`, { waitUntil: 'networkidle2' });
await page.waitForTimeout(1500);
// Screenshot the header
const screenshotPath = `/home/moltbot/clawd/test-mobile-${file.name.replace(/\//g, '-')}.png`;
await page.screenshot({ path: screenshotPath, fullPage: false });
console.log(`Screenshot saved: ${screenshotPath}`);
// Check viewport
const viewport = page.viewport();
console.log(`Viewport: ${viewport.width}x${viewport.height}`);
// Check what's visible in the header before clicking menu
const headerState = await page.evaluate(() => {
const result = {
hamburgerMenu: false,
previewButton: false,
pdfButton: false,
gitDiffButton: false,
menuButtonSelector: null
};
// Check for hamburger menu (three dots)
const selectors = [
'.file-actions-menu button',
'button[aria-label*="menu"]',
'.actions-menu button',
'button.menu-trigger',
'.header button:has-text("⋮")',
'button:contains("⋮")'
];
// Try to find the menu button
for (const sel of selectors) {
try {
const el = document.querySelector(sel);
if (el && window.getComputedStyle(el).display !== 'none') {
result.hamburgerMenu = true;
result.menuButtonSelector = sel;
break;
}
} catch (e) {}
}
// If we can't find by those selectors, look for any button with ⋮ text
if (!result.hamburgerMenu) {
const buttons = Array.from(document.querySelectorAll('button'));
const menuBtn = buttons.find(btn => btn.textContent.includes('⋮'));
if (menuBtn && window.getComputedStyle(menuBtn).display !== 'none') {
result.hamburgerMenu = true;
result.menuButtonSelector = 'button (contains ⋮)';
}
}
// Check for other buttons in header
const allButtons = Array.from(document.querySelectorAll('button'));
allButtons.forEach(btn => {
const text = btn.textContent.toLowerCase();
const style = window.getComputedStyle(btn);
if (style.display !== 'none' && style.visibility !== 'hidden') {
if (text.includes('preview')) result.previewButton = true;
if (text.includes('pdf')) result.pdfButton = true;
if (text.includes('git') || text.includes('diff')) result.gitDiffButton = true;
}
});
return result;
});
console.log('\nHeader buttons visible:');
console.log(` Hamburger Menu: ${headerState.hamburgerMenu} (selector: ${headerState.menuButtonSelector})`);
console.log(` Preview: ${headerState.previewButton}`);
console.log(` PDF: ${headerState.pdfButton}`);
console.log(` Git Diff: ${headerState.gitDiffButton}`);
// Try to click hamburger menu and check menu items
let menuClicked = false;
let menuItems = {};
if (headerState.hamburgerMenu) {
try {
// Try to find and click the menu button
const menuButtonClicked = await page.evaluate(() => {
// Look for the menu button
const buttons = Array.from(document.querySelectorAll('button'));
const menuBtn = buttons.find(btn =>
btn.textContent.includes('⋮') ||
btn.classList.contains('menu-trigger') ||
btn.getAttribute('aria-label')?.toLowerCase().includes('menu')
);
if (menuBtn) {
menuBtn.click();
return true;
}
return false;
});
if (menuButtonClicked) {
await page.waitForTimeout(500);
menuClicked = true;
// Check what's in the menu
menuItems = await page.evaluate(() => {
const items = {
preview: false,
downloadPDF: false,
gitDiff: false
};
// Look for menu items (they might be in a dropdown/popup)
const allElements = Array.from(document.querySelectorAll('*'));
allElements.forEach(el => {
const text = el.textContent?.toLowerCase() || '';
const style = window.getComputedStyle(el);
// Only count visible elements
if (style.display !== 'none' && style.visibility !== 'hidden') {
if (text === 'preview' || el.textContent?.trim() === 'Preview') items.preview = true;
if (text === 'download pdf' || el.textContent?.trim() === 'Download PDF') items.downloadPDF = true;
if (text === 'git diff' || el.textContent?.trim() === 'Git Diff') items.gitDiff = true;
}
});
return items;
});
console.log('\nMenu items visible:');
console.log(` Preview: ${menuItems.preview}`);
console.log(` Download PDF: ${menuItems.downloadPDF}`);
console.log(` Git Diff: ${menuItems.gitDiff}`);
}
} catch (error) {
console.log(`\n⚠️ Error clicking menu: ${error.message}`);
}
} else {
console.log('\n⚠ Could not find hamburger menu');
}
// Verify expectations
const issues = [];
if (!headerState.hamburgerMenu) {
issues.push('❌ Hamburger menu NOT visible on mobile');
}
if (menuClicked) {
if (file.expectPreview && !menuItems.preview) {
issues.push('❌ Preview should be in menu but is NOT');
}
if (!file.expectPreview && menuItems.preview) {
issues.push('❌ Preview should NOT be in menu but IS');
}
if (file.expectPDF && !menuItems.downloadPDF) {
issues.push('❌ Download PDF should be in menu but is NOT');
}
if (!file.expectPDF && menuItems.downloadPDF) {
issues.push('❌ Download PDF should NOT be in menu but IS');
}
if (file.expectGitDiff && !menuItems.gitDiff) {
issues.push('❌ Git Diff should be in menu but is NOT');
}
if (!file.expectGitDiff && menuItems.gitDiff) {
issues.push('❌ Git Diff should NOT be in menu but IS');
}
} else if (headerState.hamburgerMenu) {
issues.push('⚠️ Hamburger menu found but could not click it');
}
if (issues.length > 0) {
console.log('\n🔴 ISSUES FOUND:');
issues.forEach(issue => console.log(` ${issue}`));
} else {
console.log('\n✅ All checks passed');
}
results.push({
file: file.name,
status: file.status,
hamburgerVisible: headerState.hamburgerMenu,
menuClicked,
menuItems,
expected: {
preview: file.expectPreview,
pdf: file.expectPDF,
gitDiff: file.expectGitDiff
},
issues
});
} catch (error) {
console.error(`\n❌ Error testing ${file.name}:`, error.message);
results.push({
file: file.name,
error: error.message
});
}
}
await browser.close();
// Print summary
console.log('\n\n========================================');
console.log('SUMMARY');
console.log('========================================\n');
const filesWithIssues = results.filter(r => r.issues && r.issues.length > 0);
if (filesWithIssues.length === 0) {
console.log('✅ All files passed mobile menu tests!');
} else {
console.log('🔴 Files with issues:\n');
filesWithIssues.forEach(r => {
console.log(`${r.file}:`);
r.issues.forEach(issue => console.log(` ${issue}`));
console.log('');
});
}
if (consoleErrors.length > 0) {
console.log('\n⚠ Console Errors:');
consoleErrors.forEach(err => console.log(` ${err}`));
} else {
console.log('\n✅ No console errors detected');
}
// Write results to JSON
fs.writeFileSync('/home/moltbot/clawd/mobile-test-results.json', JSON.stringify(results, null, 2));
console.log('\n📄 Full results saved to: mobile-test-results.json');
})();