Files
clawd/test-mobile-files.js

272 lines
9.6 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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');
})();