Skip to main content
Glama
test-composer-storage-tracker.js•10.5 kB
#!/usr/bin/env node /** * Composer Storage Tracker - Monitor all storage operations */ import { chromium } from 'playwright'; import { readFileSync } from 'fs'; import { resolve, dirname } from 'path'; import { fileURLToPath } from 'url'; const currentDir = dirname(fileURLToPath(import.meta.url)); const tokenPath = resolve(currentDir, 'correct-jwt-new.txt'); const jwtToken = readFileSync(tokenPath, 'utf8').trim(); async function trackComposerStorage() { console.log('šŸ” Composer Storage Operation Tracker\n'); const baseURL = "https://composer.euconquisto.com/#/embed"; const orgId = "36c92686-c494-ec11-a22a-dc984041c95d"; const embedURL = `${baseURL}/auth-with-token/pt_br/home/${orgId}/${jwtToken}`; let browser; try { console.log('šŸš€ Launching browser with storage tracking...'); browser = await chromium.launch({ headless: false, devtools: true, args: ['--disable-web-security', '--disable-features=VizDisplayCompositor'] }); const context = await browser.newContext({ viewport: { width: 1280, height: 720 } }); const page = await context.newPage(); // Inject storage monitoring before navigation await page.addInitScript(() => { console.log('šŸŽÆ Storage monitoring initialized'); // Track localStorage const originalSetItem = localStorage.setItem; const originalRemoveItem = localStorage.removeItem; const originalClear = localStorage.clear; localStorage.setItem = function(key, value) { console.log(`šŸ“ localStorage.setItem("${key}", ${value?.substring(0, 100)}${value?.length > 100 ? '...' : ''})`); return originalSetItem.apply(this, arguments); }; localStorage.removeItem = function(key) { console.log(`šŸ—‘ļø localStorage.removeItem("${key}")`); return originalRemoveItem.apply(this, arguments); }; localStorage.clear = function() { console.log(`šŸ’„ localStorage.clear()`); return originalClear.apply(this, arguments); }; // Track sessionStorage const originalSessionSetItem = sessionStorage.setItem; const originalSessionRemoveItem = sessionStorage.removeItem; const originalSessionClear = sessionStorage.clear; sessionStorage.setItem = function(key, value) { console.log(`šŸ“ sessionStorage.setItem("${key}", ${value?.substring(0, 100)}${value?.length > 100 ? '...' : ''})`); return originalSessionSetItem.apply(this, arguments); }; sessionStorage.removeItem = function(key) { console.log(`šŸ—‘ļø sessionStorage.removeItem("${key}")`); return originalSessionRemoveItem.apply(this, arguments); }; sessionStorage.clear = function() { console.log(`šŸ’„ sessionStorage.clear()`); return originalSessionClear.apply(this, arguments); }; // Track IndexedDB if (window.indexedDB) { const originalOpen = indexedDB.open; indexedDB.open = function(name, version) { console.log(`šŸ—„ļø IndexedDB.open("${name}", version: ${version})`); const request = originalOpen.apply(this, arguments); request.onsuccess = function(event) { console.log(`āœ… IndexedDB opened: ${name}`); const db = event.target.result; // Monitor transactions const originalTransaction = db.transaction; db.transaction = function(storeNames, mode) { console.log(`šŸ“Š IndexedDB transaction: stores=[${storeNames}], mode=${mode}`); return originalTransaction.apply(this, arguments); }; }; return request; }; } // Track URL changes (for URL-based storage) let lastURL = window.location.href; setInterval(() => { if (window.location.href !== lastURL) { const newURL = window.location.href; console.log(`šŸ”— URL Changed:`); console.log(` From: ${lastURL}`); console.log(` To: ${newURL}`); // Check if URL contains base64 data if (newURL.includes('data=') || newURL.includes('composition=')) { console.log(` šŸ“¦ URL may contain encoded data`); } lastURL = newURL; } }, 100); }); // Enhanced console logging console.log('\nšŸ“Š Storage Monitoring Active:\n'); page.on('console', msg => { const text = msg.text(); // Highlight storage operations if (text.includes('localStorage') || text.includes('sessionStorage') || text.includes('IndexedDB')) { console.log(`\n${text}\n`); } else if (text.includes('URL Changed')) { console.log(text); } else if (text.includes('šŸ“') || text.includes('šŸ—‘ļø') || text.includes('šŸ’„') || text.includes('šŸ—„ļø') || text.includes('šŸ“Š') || text.includes('šŸ”—')) { console.log(text); } else { // Regular console messages const type = msg.type(); const emoji = { 'log': 'šŸ“', 'info': 'ā„¹ļø', 'warning': 'āš ļø', 'error': 'āŒ', 'debug': 'šŸ›' }[type] || 'šŸ“‹'; console.log(`${emoji} ${text}`); } }); // Network monitoring for storage-related calls page.on('request', request => { const url = request.url(); const method = request.method(); // Check for storage-related endpoints if (url.includes('storage') || url.includes('save') || url.includes('composition')) { console.log(`\n🌐 [${method}] Storage-related request: ${url}`); // Log POST/PUT data if (method === 'POST' || method === 'PUT') { const postData = request.postData(); if (postData) { console.log(` šŸ“¤ Data: ${postData.substring(0, 200)}${postData.length > 200 ? '...' : ''}`); } } } }); page.on('response', response => { const url = response.url(); const status = response.status(); if (url.includes('storage') || url.includes('save') || url.includes('composition')) { const emoji = status >= 400 ? 'āŒ' : 'āœ…'; console.log(` ${emoji} Response: ${status}`); } }); console.log('šŸ“” Navigating to Composer...'); await page.goto(embedURL, { waitUntil: 'networkidle', timeout: 60000 }); console.log('āœ… Page loaded\n'); // Wait for initial load await page.waitForTimeout(3000); // Periodic storage snapshot let storageSnapshot = {}; setInterval(async () => { try { const currentStorage = await page.evaluate(() => { const snapshot = {}; for (let i = 0; i < localStorage.length; i++) { const key = localStorage.key(i); snapshot[key] = localStorage.getItem(key); } return snapshot; }); // Check for changes Object.keys(currentStorage).forEach(key => { if (!storageSnapshot[key]) { console.log(`\nšŸ†• New localStorage key detected: "${key}"`); } else if (storageSnapshot[key] !== currentStorage[key]) { console.log(`\nšŸ”„ localStorage key updated: "${key}"`); } }); Object.keys(storageSnapshot).forEach(key => { if (!currentStorage[key]) { console.log(`\nāŒ localStorage key removed: "${key}"`); } }); storageSnapshot = currentStorage; } catch (e) { // Ignore errors during periodic checks } }, 2000); console.log('\n' + '═'.repeat(60)); console.log('šŸŽÆ STORAGE TRACKING ACTIVE - INTERACT WITH COMPOSER'); console.log('═'.repeat(60)); console.log('\nšŸ“‹ Tracking:'); console.log(' āœ… localStorage operations (set/remove/clear)'); console.log(' āœ… sessionStorage operations'); console.log(' āœ… IndexedDB operations'); console.log(' āœ… URL changes (for URL-based storage)'); console.log(' āœ… Storage-related network requests'); console.log(' āœ… Periodic storage snapshots\n'); console.log('šŸ’” Try creating a new composition and adding widgets!'); console.log(' All storage operations will be logged here.'); console.log(' Press Ctrl+C to end the session.\n'); console.log('═'.repeat(60) + '\n'); // Keep running indefinitely await new Promise(() => {}); } catch (error) { console.error('āŒ Error:', error.message); } } // Handle graceful shutdown process.on('SIGINT', () => { console.log('\n\nšŸ”š Ending storage tracking session...'); process.exit(0); }); trackComposerStorage().catch(console.error);

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/rkm097git/euconquisto-composer-mcp-poc'

If you have feedback or need assistance with the MCP directory API, please join our Discord server