Skip to main content
Glama
test-composer-storage-file-logger.jsโ€ข11 kB
#!/usr/bin/env node /** * Composer Storage Tracker with File Logging * Logs all storage operations to a file for later analysis */ import { chromium } from 'playwright'; import { readFileSync, writeFileSync, appendFileSync } 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 logPath = resolve(currentDir, 'composer-storage-log.txt'); const jwtToken = readFileSync(tokenPath, 'utf8').trim(); // Initialize log file writeFileSync(logPath, `Composer Storage Tracking Log - ${new Date().toISOString()}\n${'='.repeat(80)}\n\n`); function log(message) { const timestamp = new Date().toISOString(); const logEntry = `[${timestamp}] ${message}\n`; appendFileSync(logPath, logEntry); console.log(message); } async function trackComposerStorageToFile() { log('๐Ÿ” Composer Storage Operation Tracker - File Logging Mode\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 { 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'); // Create a function to send logs to console (which we'll capture) window.__logToFile = (message) => { console.log(`[STORAGE_LOG] ${message}`); }; // Track localStorage const originalSetItem = localStorage.setItem; const originalRemoveItem = localStorage.removeItem; const originalClear = localStorage.clear; localStorage.setItem = function(key, value) { const preview = value?.length > 200 ? value.substring(0, 200) + '...' : value; window.__logToFile(`localStorage.setItem("${key}", ${preview})`); return originalSetItem.apply(this, arguments); }; localStorage.removeItem = function(key) { window.__logToFile(`localStorage.removeItem("${key}")`); return originalRemoveItem.apply(this, arguments); }; localStorage.clear = function() { window.__logToFile(`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) { const preview = value?.length > 200 ? value.substring(0, 200) + '...' : value; window.__logToFile(`sessionStorage.setItem("${key}", ${preview})`); return originalSessionSetItem.apply(this, arguments); }; sessionStorage.removeItem = function(key) { window.__logToFile(`sessionStorage.removeItem("${key}")`); return originalSessionRemoveItem.apply(this, arguments); }; sessionStorage.clear = function() { window.__logToFile(`sessionStorage.clear()`); return originalSessionClear.apply(this, arguments); }; // Track IndexedDB if (window.indexedDB) { const originalOpen = indexedDB.open; indexedDB.open = function(name, version) { window.__logToFile(`IndexedDB.open("${name}", version: ${version})`); const request = originalOpen.apply(this, arguments); request.onsuccess = function(event) { window.__logToFile(`IndexedDB opened successfully: ${name}`); const db = event.target.result; // Monitor transactions const originalTransaction = db.transaction; db.transaction = function(storeNames, mode) { window.__logToFile(`IndexedDB transaction: stores=[${storeNames}], mode=${mode}`); return originalTransaction.apply(this, arguments); }; }; return request; }; } // Track URL changes let lastURL = window.location.href; setInterval(() => { if (window.location.href !== lastURL) { const newURL = window.location.href; window.__logToFile(`URL_CHANGE: ${newURL}`); // Extract and log any base64 data in URL const urlParts = newURL.split('/'); urlParts.forEach((part, index) => { if (part.length > 100 && /^[A-Za-z0-9+/]+=*$/.test(part)) { window.__logToFile(`URL_DATA[${index}]: Possible base64 data (${part.length} chars)`); } }); lastURL = newURL; } }, 100); // Monitor AJAX/Fetch for storage operations const originalFetch = window.fetch; window.fetch = function(url, options) { if (url.includes('storage') || url.includes('save') || url.includes('composition')) { window.__logToFile(`FETCH: ${options?.method || 'GET'} ${url}`); if (options?.body) { const bodyPreview = typeof options.body === 'string' ? options.body.substring(0, 500) : '[Binary/FormData]'; window.__logToFile(`FETCH_BODY: ${bodyPreview}`); } } return originalFetch.apply(this, arguments); }; }); // Capture console messages and write to file page.on('console', msg => { const text = msg.text(); if (text.includes('[STORAGE_LOG]')) { const logMessage = text.replace('[STORAGE_LOG] ', ''); log(`๐Ÿ“ ${logMessage}`); } }); // Network monitoring page.on('request', request => { const url = request.url(); const method = request.method(); if (url.includes('storage') || url.includes('save') || url.includes('composition')) { log(`๐ŸŒ [${method}] ${url}`); if (method === 'POST' || method === 'PUT') { const postData = request.postData(); if (postData) { log(` ๐Ÿ“ค Request Data: ${postData.substring(0, 500)}${postData.length > 500 ? '...' : ''}`); } } } }); page.on('response', response => { const url = response.url(); const status = response.status(); if (url.includes('storage') || url.includes('save') || url.includes('composition')) { log(` ${status >= 400 ? 'โŒ' : 'โœ…'} Response: ${status}`); } }); log('\n๐Ÿ“ก Navigating to Composer...'); await page.goto(embedURL, { waitUntil: 'networkidle', timeout: 60000 }); log('โœ… Page loaded\n'); // Wait for initial load await page.waitForTimeout(3000); // Periodic storage snapshot setInterval(async () => { try { const storageKeys = await page.evaluate(() => { const keys = []; for (let i = 0; i < localStorage.length; i++) { keys.push(localStorage.key(i)); } return keys; }); // Log current storage keys count log(`๐Ÿ“Š Storage snapshot: ${storageKeys.length} localStorage keys`); // Check for composition-related keys const compositionKeys = storageKeys.filter(key => key.toLowerCase().includes('compos') || key.toLowerCase().includes('content') || key.toLowerCase().includes('widget') ); if (compositionKeys.length > 0) { log(` ๐ŸŽฏ Composition-related keys found: ${compositionKeys.join(', ')}`); } } catch (e) { // Ignore errors during periodic checks } }, 10000); // Every 10 seconds log('\n' + 'โ•'.repeat(80)); log('๐ŸŽฏ STORAGE TRACKING ACTIVE - File: composer-storage-log.txt'); log('โ•'.repeat(80)); log('\n๐Ÿ“‹ Instructions:'); log(' 1. Click "Nova Composiรงรฃo" button'); log(' 2. Configure composition settings'); log(' 3. Add widgets to your composition'); log(' 4. Save the composition'); log(' 5. When done, close the browser or press Ctrl+C'); log('\n๐Ÿ’พ All operations are being logged to: composer-storage-log.txt'); log(' Take your time - there are no time restrictions!'); log('โ•'.repeat(80) + '\n'); console.log('\nโœ… Browser is ready for interaction!'); console.log('๐Ÿ“‚ Check composer-storage-log.txt for the complete log after your session.\n'); // Keep running indefinitely await new Promise(() => {}); } catch (error) { log(`โŒ Error: ${error.message}`); } } // Handle graceful shutdown process.on('SIGINT', () => { log('\n\n๐Ÿ”š Storage tracking session ended by user'); console.log('\n๐Ÿ“‚ Complete log saved to: composer-storage-log.txt'); process.exit(0); }); trackComposerStorageToFile().catch(error => { log(`๐Ÿ’ฅ Fatal error: ${error.message}`); console.error(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