Files
cv-site/tests/mjs/32-hyperscript-multi-src.test.mjs
T

285 lines
12 KiB
JavaScript
Raw Normal View History

/**
* Test: Hyperscript Multiple External SRC Files Bug Investigation
*
* HYPOTHESIS: Hyperscript 0.9.14 has issues when loading multiple
* <script type="text/hyperscript" src="..."> files, even though:
* - Each file parses correctly individually
* - All content works when concatenated inline
*
* This test aims to create a minimal reproducible case.
*/
import puppeteer from 'puppeteer';
const BASE_URL = 'http://localhost:1999';
async function testMultiFileSrcBug() {
console.log('🧪 HYPERSCRIPT MULTI-SRC FILE BUG INVESTIGATION\n');
console.log('=' .repeat(70) + '\n');
const browser = await puppeteer.launch({
headless: false,
args: ['--no-sandbox', '--disable-setuid-sandbox'],
defaultViewport: { width: 1280, height: 900 }
});
const page = await browser.newPage();
// Collect console messages and errors
const consoleMessages = [];
const errors = [];
page.on('console', msg => {
consoleMessages.push({ type: msg.type(), text: msg.text() });
if (msg.type() === 'error') {
console.log(` ❌ Console Error: ${msg.text()}`);
}
});
page.on('pageerror', error => {
errors.push(error.message);
console.log(` ❌ Page Error: ${error.message}`);
});
try {
// =====================================================================
// TEST 1: Load actual CV page and check hyperscript status
// =====================================================================
console.log('1️⃣ Loading CV page to check hyperscript file loading...\n');
await page.goto(BASE_URL, { waitUntil: 'networkidle2', timeout: 30000 });
// Check which hyperscript files were loaded
const scriptTags = await page.evaluate(() => {
const scripts = document.querySelectorAll('script[type="text/hyperscript"]');
return Array.from(scripts).map(s => ({
src: s.src || 'INLINE',
hasContent: s.textContent.length > 0,
contentLength: s.textContent.length,
contentPreview: s.textContent.substring(0, 100)
}));
});
console.log(` Found ${scriptTags.length} hyperscript script tags:\n`);
scriptTags.forEach((tag, i) => {
if (tag.src === 'INLINE') {
console.log(` ${i + 1}. INLINE (${tag.contentLength} chars)`);
} else {
console.log(` ${i + 1}. SRC: ${tag.src}`);
}
});
console.log();
// =====================================================================
// TEST 2: Check if hyperscript is loaded and functioning
// =====================================================================
console.log('2️⃣ Checking hyperscript functionality...\n');
const hyperscriptStatus = await page.evaluate(() => {
return {
hyperscriptExists: typeof _hyperscript !== 'undefined',
browserUtilsExists: typeof _hyperscript !== 'undefined' && _hyperscript.browserInit,
initScrollBehaviorExists: typeof initScrollBehavior === 'function',
handleScrollExists: typeof handleScroll === 'function',
printFriendlyExists: typeof printFriendly === 'function'
};
});
console.log(` _hyperscript loaded: ${hyperscriptStatus.hyperscriptExists ? '✅' : '❌'}`);
console.log(` initScrollBehavior: ${hyperscriptStatus.initScrollBehaviorExists ? '✅' : '❌'}`);
console.log(` handleScroll: ${hyperscriptStatus.handleScrollExists ? '✅' : '❌'}`);
console.log(` printFriendly: ${hyperscriptStatus.printFriendlyExists ? '✅' : '❌'}`);
console.log();
// =====================================================================
// TEST 3: Test keyboard shortcuts (which use inline hyperscript)
// =====================================================================
console.log('3️⃣ Testing keyboard shortcuts (inline hyperscript)...\n');
// Test '?' shortcut to open shortcuts modal
await page.keyboard.press('?');
await new Promise(r => setTimeout(r, 500));
const shortcutsModalOpen = await page.evaluate(() => {
const modal = document.getElementById('shortcuts-modal');
return modal && modal.open;
});
console.log(` '?' key opens shortcuts modal: ${shortcutsModalOpen ? '✅ WORKS' : '❌ FAILS'}`);
// Close modal
if (shortcutsModalOpen) {
await page.keyboard.press('Escape');
await new Promise(r => setTimeout(r, 300));
}
// Test 'V' shortcut to toggle theme
const themeStateBefore = await page.evaluate(() => {
const toggle = document.getElementById('themeToggle');
return toggle ? toggle.checked : null;
});
await page.keyboard.press('v');
await new Promise(r => setTimeout(r, 300));
const themeStateAfter = await page.evaluate(() => {
const toggle = document.getElementById('themeToggle');
return toggle ? toggle.checked : null;
});
const vKeyWorks = themeStateBefore !== null && themeStateAfter !== null && themeStateBefore !== themeStateAfter;
console.log(` 'V' key toggles theme: ${vKeyWorks ? '✅ WORKS' : '❌ FAILS'}`);
console.log();
// =====================================================================
// TEST 4: Test scroll behavior (uses external file functions)
// =====================================================================
console.log('4️⃣ Testing scroll behavior (external file functions)...\n');
// Scroll down
await page.evaluate(() => window.scrollTo(0, 500));
await new Promise(r => setTimeout(r, 500));
const scrollDownResult = await page.evaluate(() => {
const actionBar = document.querySelector('.action-bar');
return actionBar ? actionBar.classList.contains('header-hidden') : null;
});
console.log(` Header hides on scroll down: ${scrollDownResult ? '✅ WORKS' : scrollDownResult === false ? '⚠️ Not hidden (mobile mode?)' : '❌ FAILS'}`);
// Scroll back up
await page.evaluate(() => window.scrollTo(0, 0));
await new Promise(r => setTimeout(r, 500));
const scrollUpResult = await page.evaluate(() => {
const actionBar = document.querySelector('.action-bar');
return actionBar ? !actionBar.classList.contains('header-hidden') : null;
});
console.log(` Header shows on scroll up: ${scrollUpResult ? '✅ WORKS' : '❌ FAILS'}`);
console.log();
// =====================================================================
// TEST 5: Create minimal reproduction page
// =====================================================================
console.log('5️⃣ Creating minimal reproduction test page...\n');
// Create a new page with minimal multi-file setup
const testPage = await browser.newPage();
testPage.on('console', msg => {
if (msg.type() === 'error') {
console.log(` ❌ Test Page Error: ${msg.text()}`);
}
});
testPage.on('pageerror', error => {
console.log(` ❌ Test Page Exception: ${error.message}`);
});
// Create test HTML that loads hyperscript like the CV does
const testHTML = `
<!DOCTYPE html>
<html>
<head>
<title>Hyperscript Multi-File Test</title>
<script type="text/hyperscript" src="/static/hyperscript/utils._hs"></script>
<script type="text/hyperscript" src="/static/hyperscript/toggles._hs"></script>
<script type="text/hyperscript" src="/static/hyperscript/hover-sync._hs"></script>
<script type="text/hyperscript" src="/static/hyperscript/keyboard._hs"></script>
<script src="https://unpkg.com/hyperscript.org@0.9.14"></script>
</head>
<body>
<h1>Multi-File Hyperscript Test</h1>
<div id="test-target">Original</div>
<button id="test-btn" _="on click put 'Clicked!' into #test-target">Click Me</button>
<div id="status"></div>
<script>
document.getElementById('status').textContent =
'initScrollBehavior: ' + (typeof initScrollBehavior === 'function' ? 'YES' : 'NO') +
', handleScroll: ' + (typeof handleScroll === 'function' ? 'YES' : 'NO') +
', printFriendly: ' + (typeof printFriendly === 'function' ? 'YES' : 'NO');
</script>
</body>
</html>
`;
// We can't serve arbitrary HTML, but we can check the existing hyperscript files
console.log(' Checking hyperscript file contents from server...\n');
// Fetch each hyperscript file
const hsFiles = [
'/static/hyperscript/utils._hs',
'/static/hyperscript/toggles._hs',
'/static/hyperscript/hover-sync._hs',
'/static/hyperscript/keyboard._hs'
];
for (const file of hsFiles) {
try {
const response = await page.evaluate(async (url) => {
const res = await fetch(url);
const text = await res.text();
return {
status: res.status,
contentType: res.headers.get('content-type'),
length: text.length,
preview: text.substring(0, 200)
};
}, BASE_URL + file);
console.log(` ${file}:`);
console.log(` Status: ${response.status}, Size: ${response.length} chars`);
console.log(` Content-Type: ${response.contentType}`);
} catch (err) {
console.log(` ${file}: ❌ Error - ${err.message}`);
}
}
await testPage.close();
// =====================================================================
// SUMMARY
// =====================================================================
console.log('\n' + '=' .repeat(70));
console.log('📊 TEST SUMMARY\n');
const allWorking = shortcutsModalOpen && vKeyWorks && (scrollDownResult !== null) && (scrollUpResult !== null);
if (allWorking) {
console.log(' ✅ All hyperscript features are working!');
console.log(' ✅ Both inline and external file functions work correctly.');
console.log('\n CONCLUSION: No multi-file bug detected in current setup.');
console.log(' The previous errors may have been caused by:');
console.log(' - Syntax errors in the refactored code');
console.log(' - Order of script loading');
console.log(' - Content-Type headers for ._hs files');
} else {
console.log(' ⚠️ Some features not working. Check errors above.');
console.log('\n This may indicate a multi-file loading issue.');
}
console.log('\n Console errors detected: ' + consoleMessages.filter(m => m.type === 'error').length);
console.log(' Page errors detected: ' + errors.length);
if (errors.length > 0) {
console.log('\n Error details:');
errors.forEach((err, i) => console.log(` ${i + 1}. ${err}`));
}
console.log('\n' + '=' .repeat(70));
console.log('\nBrowser staying open for manual inspection...');
console.log('Press Ctrl+C when done.\n');
// Keep browser open for inspection
await new Promise(() => {});
} catch (error) {
console.error('Test error:', error);
await browser.close();
process.exit(1);
}
}
testMultiFileSrcBug();