- Unified localStorage key to 'theme-preference' across all components
- Fixed header.tsx using wrong localStorage key ('theme' instead of 'theme-preference')
- Added localStorage hybrid persistence for instant theme changes
- Removed router.refresh() which was causing stale data revert
- Replaced Blue theme with Sepia
- Consolidated auth() calls to prevent race conditions
- Updated UserSettingsData types to include all themes
93 lines
3.0 KiB
TypeScript
93 lines
3.0 KiB
TypeScript
/**
|
|
* Playwright test script to diagnose MasonryGrid hot reload issue
|
|
*/
|
|
|
|
const { chromium } = require('playwright');
|
|
|
|
async function testMasonryLayout() {
|
|
console.log('🔍 Starting Masonry layout diagnosis...');
|
|
|
|
const browser = await chromium.launch({
|
|
headless: false, // Show browser for visual inspection
|
|
slowMo: 50, // Slow down actions for better visibility
|
|
});
|
|
|
|
const context = await browser.newContext({
|
|
viewport: { width: 1920, height: 1080 }
|
|
});
|
|
|
|
const page = await context.newPage();
|
|
|
|
// Navigate to the app
|
|
await page.goto('http://localhost:3000');
|
|
|
|
// Wait for page to load
|
|
await page.waitForTimeout(3000);
|
|
|
|
// Take screenshot of initial state
|
|
await page.screenshot({ path: 'masonry-before.png', fullPage: true });
|
|
console.log('📸 Screenshot saved: masonry-before.png');
|
|
|
|
// Check DOM for MasonryItem elements
|
|
const masonryItems = await page.$$eval('.masonry-item', (items) => {
|
|
return items.map(item => ({
|
|
hasDataSize: item.hasAttribute('data-size'),
|
|
dataSize: item.getAttribute('data-size'),
|
|
hasStyle: item.hasAttribute('style'),
|
|
style: item.getAttribute('style'),
|
|
className: item.className,
|
|
computedWidth: window.getComputedStyle(item).width,
|
|
}));
|
|
});
|
|
|
|
console.log('🎯 MasonryItem analysis:');
|
|
console.table(masonryItems);
|
|
|
|
// Check which items have inline styles
|
|
const itemsWithInlineStyle = masonryItems.filter(item => item.hasStyle);
|
|
console.log(`✓ Items with inline style attribute: ${itemsWithInlineStyle.length}/${masonryItems.length}`);
|
|
|
|
// Check which items have data-size attribute
|
|
const itemsWithDataSize = masonryItems.filter(item => item.hasDataSize);
|
|
console.log(`✓ Items with data-size attribute: ${itemsWithDataSize.length}/${masonryItems.length}`);
|
|
|
|
// Analyze computed widths
|
|
const uniqueWidths = [...new Set(masonryItems.map(item => item.computedWidth))];
|
|
console.log(`📏 Unique computed widths found:`, uniqueWidths);
|
|
|
|
// Check if Muuri is initialized
|
|
const muuriStatus = await page.evaluate(() => {
|
|
const gridElement = document.querySelector('.muuri-item');
|
|
if (!gridElement) return 'No Muuri grid found';
|
|
|
|
const gridRect = gridElement.getBoundingClientRect();
|
|
const muuriContainer = gridElement.parentElement;
|
|
|
|
if (muuriContainer) {
|
|
const containerRect = muuriContainer.getBoundingClientRect();
|
|
return {
|
|
gridRect,
|
|
containerRect,
|
|
isMuuriInitialized: true,
|
|
};
|
|
}
|
|
|
|
return 'Muuri not initialized';
|
|
});
|
|
|
|
console.log('\n🧩 Muuri grid status:', muuriStatus);
|
|
|
|
// Take second screenshot after analysis
|
|
await page.screenshot({ path: 'masonry-after-analysis.png', fullPage: true });
|
|
console.log('📸 Screenshot saved: masonry-after-analysis.png');
|
|
|
|
// Keep browser open for manual inspection
|
|
console.log('\n⏳ Keeping browser open for 30 seconds for manual inspection...');
|
|
await page.waitForTimeout(30000);
|
|
|
|
await browser.close();
|
|
console.log('✅ Test complete');
|
|
}
|
|
|
|
testMasonryLayout().catch(console.error);
|