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);
});