import { chromium } from 'playwright'; (async () => { console.log('=== DEBUGGING PARAMETER DISPLAY ===\n'); const browser = await chromium.launch({ headless: false, slowMo: 500 }); const context = await browser.newContext(); const page = await context.newPage(); const issues = []; const successes = []; // Capture console messages page.on('console', msg => { const text = msg.text(); console.log(`[BROWSER CONSOLE] ${msg.type()}: ${text}`); }); // Capture network requests const apiResponses = []; page.on('response', async (response) => { const url = response.url(); if (url.includes('/api/action-mappings') || url.includes('actionmappings')) { try { const json = await response.json(); apiResponses.push({ url, status: response.status(), data: json }); console.log(`[API RESPONSE] ${url} - Status: ${response.status()}`); } catch (e) { console.log(`[API RESPONSE] ${url} - Status: ${response.status()} (non-JSON)`); } } }); try { console.log('\nšŸ“± STEP 1: Loading app and logging in...'); await page.goto('http://100.81.138.77:8081/', { waitUntil: 'networkidle', timeout: 60000 }); await page.waitForTimeout(2000); await page.screenshot({ path: 'debug-1-homepage.png', fullPage: true }); // Login await page.click('body'); await page.waitForTimeout(500); await page.keyboard.press('Tab'); await page.waitForTimeout(300); await page.keyboard.type('admin', { delay: 50 }); await page.waitForTimeout(300); await page.keyboard.press('Tab'); await page.waitForTimeout(300); await page.keyboard.type('admin123', { delay: 50 }); await page.waitForTimeout(300); await page.keyboard.press('Enter'); await page.waitForTimeout(4000); console.log('āœ… Login successful\n'); console.log('šŸ“± STEP 2: Navigate to Action Mappings...'); await page.goto('http://100.81.138.77:8081/#/action-mappings', { waitUntil: 'networkidle', timeout: 60000 }); await page.waitForTimeout(2000); await page.screenshot({ path: 'debug-2-action-mappings-page.png', fullPage: true }); successes.push('Navigated to action mappings page'); console.log('\nšŸ“± STEP 3: Download mappings from server...'); // Tab to download button and click for (let i = 0; i < 3; i++) { await page.keyboard.press('Tab'); await page.waitForTimeout(300); } await page.keyboard.press('Enter'); await page.waitForTimeout(8000); // Wait longer for download await page.screenshot({ path: 'debug-3-after-download.png', fullPage: true }); console.log('\nšŸ” STEP 4: Analyzing API responses...'); if (apiResponses.length > 0) { console.log(`Found ${apiResponses.length} API response(s)\n`); apiResponses.forEach((resp, idx) => { console.log(`\nAPI Response ${idx + 1}:`); console.log(` URL: ${resp.url}`); console.log(` Status: ${resp.status}`); if (Array.isArray(resp.data)) { console.log(` Mappings count: ${resp.data.length}`); // Check first mapping for parameters if (resp.data.length > 0) { const first = resp.data[0]; console.log(`\n First mapping analysis:`); console.log(` Name: ${first.name}`); console.log(` Has input_actions: ${!!first.input_actions}`); console.log(` Has output_actions: ${!!first.output_actions}`); if (first.input_actions && first.input_actions.length > 0) { const inputAction = first.input_actions[0]; console.log(` Input action: ${inputAction.action}`); console.log(` Input parameters:`, inputAction.parameters); if (Object.keys(inputAction.parameters || {}).length > 0) { successes.push('API returns input parameters'); } else { issues.push('API input_actions has no parameters'); } } if (first.output_actions && first.output_actions.length > 0) { const outputAction = first.output_actions[0]; console.log(` Output action: ${outputAction.action}`); console.log(` Output parameters:`, outputAction.parameters); if (Object.keys(outputAction.parameters || {}).length > 0) { successes.push('API returns output parameters'); } else { issues.push('API output_actions has no parameters'); } } } } }); } else { issues.push('No API responses captured'); } console.log('\n\nšŸ” STEP 5: Checking DOM for UI elements...'); // Check for ExpansionTile elements const expansionTileCount = await page.locator('[role="button"]').count(); console.log(` ExpansionTile elements (role=button): ${expansionTileCount}`); if (expansionTileCount > 0) { successes.push(`Found ${expansionTileCount} ExpansionTile elements`); } else { issues.push('No ExpansionTile elements found - might still be using ListTile'); } // Check for parameter badges const paramBadgeCount = await page.locator('text=/\\d+ params?/').count(); console.log(` Parameter badges (e.g., "2 params"): ${paramBadgeCount}`); if (paramBadgeCount > 0) { successes.push(`Found ${paramBadgeCount} parameter badges`); } else { issues.push('No parameter count badges visible'); } // Check for any cards const cardCount = await page.locator('.card, [class*="card"]').count(); console.log(` Card elements: ${cardCount}`); console.log('\n\nšŸ” STEP 6: Trying to expand first mapping...'); if (expansionTileCount > 0) { const firstTile = page.locator('[role="button"]').first(); // Get the text content before expanding const tileText = await firstTile.textContent(); console.log(` First tile text: ${tileText.substring(0, 100)}...`); await firstTile.click(); await page.waitForTimeout(2000); await page.screenshot({ path: 'debug-4-expanded-tile.png', fullPage: true }); // Check for parameter display in expanded content const hasGCoreServer = await page.locator('text=GCoreServer:').count(); const hasPTZHead = await page.locator('text=PTZ head:').count(); const hasCaption = await page.locator('text=Caption:').count(); const hasInputParams = await page.locator('text=Input Parameters').count(); const hasOutputParams = await page.locator('text=/Output Action \\d+:/').count(); console.log(`\n Expanded content check:`); console.log(` "GCoreServer:" found: ${hasGCoreServer}`); console.log(` "PTZ head:" found: ${hasPTZHead}`); console.log(` "Caption:" found: ${hasCaption}`); console.log(` "Input Parameters" header: ${hasInputParams}`); console.log(` "Output Action N:" headers: ${hasOutputParams}`); if (hasGCoreServer > 0 || hasPTZHead > 0 || hasCaption > 0) { successes.push('Parameter details visible in expanded view!'); } else if (hasInputParams > 0 || hasOutputParams > 0) { issues.push('Parameter headers visible but no actual parameter values shown'); } else { issues.push('No parameter content visible in expanded view'); } } console.log('\n\nšŸ” STEP 7: Checking JavaScript bundle version...'); // Check main.dart.js timestamp or hash const scriptTags = await page.evaluate(() => { const scripts = Array.from(document.querySelectorAll('script[src]')); return scripts.map(s => ({ src: s.src })); }); console.log(` Found ${scriptTags.length} script tags:`); scriptTags.forEach(script => { console.log(` ${script.src}`); if (script.src.includes('main.dart.js')) { successes.push('main.dart.js is loaded'); } }); console.log('\n\nšŸ” STEP 8: Checking for cached resources...'); const cacheStatus = await page.evaluate(() => { return { serviceWorker: 'serviceWorker' in navigator, caches: 'caches' in window }; }); console.log(` Service Worker support: ${cacheStatus.serviceWorker}`); console.log(` Cache API support: ${cacheStatus.caches}`); if (cacheStatus.serviceWorker || cacheStatus.caches) { issues.push('Browser may be caching old code'); } } catch (error) { console.error('\nšŸ’„ ERROR DURING DEBUG:', error.message); issues.push(`Test error: ${error.message}`); await page.screenshot({ path: 'debug-error.png', fullPage: true }); } console.log('\n\n' + '='.repeat(80)); console.log('DEBUG SUMMARY'); console.log('='.repeat(80)); if (successes.length > 0) { console.log('\nāœ… SUCCESSES:'); successes.forEach(s => console.log(` āœ“ ${s}`)); } if (issues.length > 0) { console.log('\nāŒ ISSUES FOUND:'); issues.forEach((issue, idx) => console.log(` ${idx + 1}. ${issue}`)); } console.log('\nšŸ“ø Screenshots saved:'); console.log(' - debug-1-homepage.png'); console.log(' - debug-2-action-mappings-page.png'); console.log(' - debug-3-after-download.png'); console.log(' - debug-4-expanded-tile.png'); console.log('\n' + '='.repeat(80)); await page.waitForTimeout(3000); await browser.close(); })();