Add modal click Playwright test utilities
This commit is contained in:
@@ -0,0 +1,147 @@
|
||||
// test_modal_click.js
|
||||
// Playwright test to debug modal click functionality
|
||||
|
||||
const { chromium } = require('playwright');
|
||||
|
||||
const TARGET_URL = 'http://192.168.254.12:8000';
|
||||
|
||||
(async () => {
|
||||
const browser = await chromium.launch({ headless: true });
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
|
||||
// Log console messages
|
||||
page.on('console', msg => console.log(`[CONSOLE] ${msg.type()}: ${msg.text()}`));
|
||||
page.on('pageerror', exc => console.log(`[PAGE ERROR] ${exc.message}`));
|
||||
|
||||
try {
|
||||
console.log(`\n🔍 [TEST] Navigating to ${TARGET_URL}...`);
|
||||
await page.goto(TARGET_URL, { waitUntil: 'networkidle' });
|
||||
console.log('✅ Page loaded');
|
||||
|
||||
console.log('[WAIT] Waiting for models container to populate...');
|
||||
try {
|
||||
await page.waitForSelector('[data-model-key]', { timeout: 5000 });
|
||||
console.log('✅ [SUCCESS] Models loaded - found cards with data-model-key attribute');
|
||||
} catch (e) {
|
||||
console.log(`❌ [FAILURE] No models found: ${e.message}`);
|
||||
const content = await page.content();
|
||||
console.log('\n📋 Page content (first 1000 chars):');
|
||||
console.log(content.substring(0, 1000));
|
||||
await browser.close();
|
||||
return;
|
||||
}
|
||||
|
||||
// Get all model cards
|
||||
const cards = await page.locator('[data-model-key]').all();
|
||||
console.log(`\n📊 Found ${cards.length} model cards`);
|
||||
|
||||
if (cards.length === 0) {
|
||||
console.log('❌ No cards found');
|
||||
await browser.close();
|
||||
return;
|
||||
}
|
||||
|
||||
// Get first card info
|
||||
const firstCard = cards[0];
|
||||
const modelKey = await firstCard.getAttribute('data-model-key');
|
||||
console.log(`\n🎯 [TARGET] First card data-model-key: ${modelKey}`);
|
||||
|
||||
// Get modal state BEFORE click
|
||||
const modalElement = page.locator('#model-details-modal');
|
||||
const modalExists = await modalElement.count() > 0;
|
||||
|
||||
if (!modalExists) {
|
||||
console.log('\n❌ [ERROR] Modal element #model-details-modal not found!');
|
||||
await browser.close();
|
||||
return;
|
||||
}
|
||||
|
||||
const classAttributeBefore = await modalElement.getAttribute('class');
|
||||
const isHiddenBefore = classAttributeBefore && classAttributeBefore.includes('hidden');
|
||||
|
||||
console.log(`\n📍 [BEFORE CLICK] Modal HTML class: '${classAttributeBefore}'`);
|
||||
console.log(` Is hidden: ${isHiddenBefore}`);
|
||||
|
||||
// Check if app is initialized
|
||||
const appExists = await page.evaluate(() => typeof window.llmMonitorApp !== 'undefined');
|
||||
console.log(` App initialized: ${appExists}`);
|
||||
|
||||
// Check localStorage
|
||||
const localStorage = await page.evaluate(() => JSON.stringify(Object.fromEntries(Object.entries(window.localStorage))));
|
||||
const lsData = JSON.parse(localStorage);
|
||||
console.log(` localStorage keys: ${Object.keys(lsData).join(', ')}`);
|
||||
|
||||
// PERFORM CLICK
|
||||
console.log(`\n🖱️ [CLICK] Clicking on model card...`);
|
||||
await firstCard.click();
|
||||
|
||||
// Brief pause for DOM update
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
// Get modal state AFTER click
|
||||
const classAttributeAfter = await modalElement.getAttribute('class');
|
||||
const isHiddenAfter = classAttributeAfter && classAttributeAfter.includes('hidden');
|
||||
|
||||
console.log(`\n📍 [AFTER CLICK] Modal HTML class: '${classAttributeAfter}'`);
|
||||
console.log(` Is hidden: ${isHiddenAfter}`);
|
||||
|
||||
// Evaluate if modal is visible
|
||||
const modalState = await page.evaluate(() => {
|
||||
const modal = document.getElementById('model-details-modal');
|
||||
if (!modal) return 'NOT_FOUND';
|
||||
const isHidden = modal.classList.contains('hidden');
|
||||
const computedStyle = window.getComputedStyle(modal);
|
||||
return {
|
||||
hasHiddenClass: isHidden,
|
||||
display: computedStyle.display,
|
||||
visibility: computedStyle.visibility,
|
||||
opacity: computedStyle.opacity,
|
||||
zIndex: computedStyle.zIndex
|
||||
};
|
||||
});
|
||||
|
||||
console.log(`\n💻 [DOM CHECK] Modal computed state:`);
|
||||
console.log(JSON.stringify(modalState, null, 3));
|
||||
|
||||
// Check for event listeners and app methods
|
||||
const appState = await page.evaluate(() => {
|
||||
const card = document.querySelector('[data-model-key]');
|
||||
if (!card) return 'NO_CARDS';
|
||||
|
||||
if (window.llmMonitorApp && typeof window.llmMonitorApp.showModelDetails === 'function') {
|
||||
return 'APP_METHOD_EXISTS';
|
||||
}
|
||||
return 'NO_APP_METHOD';
|
||||
});
|
||||
|
||||
console.log(`\n🔗 [LISTENERS] Event handler state: ${appState}`);
|
||||
|
||||
// Take screenshot
|
||||
const screenshotPath = '/tmp/modal-test-after-click.png';
|
||||
await page.screenshot({ path: screenshotPath });
|
||||
console.log(`\n📸 Screenshot saved: ${screenshotPath}`);
|
||||
|
||||
// Final verdict
|
||||
console.log('\n' + '='.repeat(70));
|
||||
if (isHiddenBefore !== undefined && isHiddenAfter !== undefined) {
|
||||
if (isHiddenBefore && !isHiddenAfter) {
|
||||
console.log('✅ [PASS] Modal successfully opened on click!');
|
||||
} else if (isHiddenBefore && isHiddenAfter) {
|
||||
console.log('❌ [FAIL] Modal still has "hidden" class after click');
|
||||
console.log(' → Event handler may not be attached');
|
||||
console.log(' → app.js may not be loaded/initialized');
|
||||
} else {
|
||||
console.log('⚠️ [UNCLEAR] Unexpected modal state');
|
||||
}
|
||||
} else {
|
||||
console.log('❌ [ERROR] Could not compare modal states');
|
||||
}
|
||||
console.log('='.repeat(70));
|
||||
|
||||
} catch (error) {
|
||||
console.error('Test error:', error.message);
|
||||
} finally {
|
||||
await browser.close();
|
||||
}
|
||||
})();
|
||||
Reference in New Issue
Block a user