Skip to main content
Glama
test-composer-interactive.js•7.36 kB
#!/usr/bin/env node /** * Interactive Composer Test - Keep browser open and log activity */ 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 interactiveComposerTest() { console.log('🌐 Interactive Composer Test - Browser will stay open\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}`; console.log('šŸ“‹ Access Details:'); console.log(` - JWT Token Length: ${jwtToken.length} characters`); console.log(` - Contains VyX0: ${jwtToken.includes('VyX0')}`); console.log(` - Contains NEsta: ${jwtToken.includes('NEsta')}`); console.log(` - Contains WEJLam: ${jwtToken.includes('WEJLam')}`); let browser; try { console.log('\nšŸš€ Launching browser (will stay open for interaction)...'); browser = await chromium.launch({ headless: false, devtools: true, // Open DevTools args: ['--disable-web-security', '--disable-features=VizDisplayCompositor'] }); const context = await browser.newContext({ viewport: { width: 1280, height: 720 }, userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36' }); const page = await context.newPage(); // Enhanced console logging console.log('\nšŸ“Š Console & Network Monitoring Active:\n'); page.on('console', msg => { const type = msg.type(); const text = msg.text(); const location = msg.location(); const emoji = { 'log': 'šŸ“', 'info': 'ā„¹ļø', 'warning': 'āš ļø', 'error': 'āŒ', 'debug': 'šŸ›' }[type] || 'šŸ“‹'; console.log(`${emoji} [${type.toUpperCase()}] ${text}`); if (location.url) { console.log(` └─ at ${location.url}:${location.lineNumber}`); } }); // Network request logging page.on('request', request => { const method = request.method(); const url = request.url(); if (!url.includes('font') && !url.includes('.woff')) { // Skip font requests console.log(`🌐 [${method}] ${url.substring(0, 100)}${url.length > 100 ? '...' : ''}`); } }); // Network response logging page.on('response', response => { const status = response.status(); const url = response.url(); if (!url.includes('font') && !url.includes('.woff')) { const emoji = status >= 400 ? 'āŒ' : status >= 300 ? 'ā†©ļø' : 'āœ…'; console.log(`${emoji} [${status}] ${url.substring(0, 100)}${url.length > 100 ? '...' : ''}`); // Log error details if (status >= 400) { response.text().then(body => { if (body && body.length < 500) { console.log(` └─ Error: ${body}`); } }).catch(() => {}); } } }); // Page errors page.on('pageerror', error => { console.log(`šŸ’„ [PAGE ERROR] ${error.message}`); }); console.log('\nšŸ“” Navigating to Composer...'); await page.goto(embedURL, { waitUntil: 'networkidle', timeout: 60000 }); console.log('āœ… Initial page load complete'); // Wait for dynamic content await page.waitForTimeout(5000); // Check for buttons and their details console.log('\nšŸ” Checking available buttons:'); const buttons = await page.locator('button').all(); for (let i = 0; i < buttons.length; i++) { try { const text = await buttons[i].textContent(); const isVisible = await buttons[i].isVisible(); const isEnabled = await buttons[i].isEnabled(); console.log(` Button ${i + 1}: "${text?.trim() || 'No text'}" - Visible: ${isVisible}, Enabled: ${isEnabled}`); // Try to get button attributes const id = await buttons[i].getAttribute('id'); const className = await buttons[i].getAttribute('class'); if (id) console.log(` └─ ID: ${id}`); if (className) console.log(` └─ Class: ${className}`); } catch (e) { console.log(` Button ${i + 1}: Could not read details`); } } // Check for other interactive elements console.log('\nšŸ” Checking other interactive elements:'); const links = await page.locator('a').count(); const inputs = await page.locator('input').count(); const selects = await page.locator('select').count(); console.log(` - Links: ${links}`); console.log(` - Input fields: ${inputs}`); console.log(` - Select dropdowns: ${selects}`); // Monitor for dynamic changes console.log('\nšŸ‘€ Monitoring for UI changes...'); // Set up mutation observer to detect DOM changes await page.evaluate(() => { const observer = new MutationObserver((mutations) => { mutations.forEach((mutation) => { if (mutation.type === 'childList' && mutation.addedNodes.length > 0) { mutation.addedNodes.forEach((node) => { if (node.nodeType === 1) { // Element node console.log(`DOM Added: ${node.tagName} ${node.id ? '#' + node.id : ''} ${node.className || ''}`); } }); } }); }); observer.observe(document.body, { childList: true, subtree: true }); }); console.log('\n' + '═'.repeat(60)); console.log('šŸŽÆ BROWSER SESSION IS NOW INTERACTIVE'); console.log(' - Interact with the UI as needed'); console.log(' - All console and network activity will be logged here'); console.log(' - Press Ctrl+C to close the browser and end the session'); console.log('═'.repeat(60) + '\n'); // Keep the script running await new Promise(() => {}); // This will run indefinitely until Ctrl+C } catch (error) { console.error(`\nāŒ Error: ${error.message}`); } } // Handle graceful shutdown process.on('SIGINT', () => { console.log('\n\nšŸ”š Closing browser session...'); process.exit(0); }); interactiveComposerTest().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