import { chromium } from 'playwright'; (async () => { console.log('=== Verifying Sync Fix ===\n'); const browser = await chromium.launch({ headless: false, slowMo: 500 }); const context = await browser.newContext(); const page = await context.newPage(); let syncSuccess = false; let syncError = null; let apiCalls = []; page.on('console', msg => { const text = msg.text(); // Capture sync-related messages if (text.toLowerCase().includes('sync')) { console.log(`[APP] ${text}`); if (text.toLowerCase().includes('success')) { syncSuccess = true; } else if (text.toLowerCase().includes('fail') || text.toLowerCase().includes('error')) { syncError = text; } } }); // Capture API calls page.on('request', request => { const url = request.url(); if (url.includes('/configuration/action-mappings') && request.method() !== 'GET') { const method = request.method(); const postData = request.postData(); apiCalls.push({ method, url, body: postData }); console.log(`\n📤 ${method} ${url}`); if (postData) { try { const json = JSON.parse(postData); console.log(` Request body:`); console.log(` - name: ${json.name}`); console.log(` - input_actions: ${JSON.stringify(json.input_actions)}`); console.log(` - output_actions: ${JSON.stringify(json.output_actions)}`); } catch (e) { console.log(` Body: ${postData.substring(0, 200)}...`); } } } }); page.on('response', async response => { const url = response.url(); if (url.includes('/configuration/action-mappings') && response.request().method() !== 'GET') { const status = response.status(); const method = response.request().method(); console.log(`📥 ${method} Response: ${status}`); if (status >= 200 && status < 300) { console.log(`✅ ${method} succeeded`); if (method === 'PUT') { syncSuccess = true; } } else { try { const body = await response.text(); console.log(`❌ ${method} failed: ${body}`); syncError = `${method} ${status}: ${body}`; } catch (e) { syncError = `${method} ${status}`; } } } }); try { // Login console.log('1️⃣ Login...'); await page.goto('http://100.81.138.77:8081/', { waitUntil: 'networkidle', timeout: 60000 }); await page.waitForTimeout(3000); 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('\n2️⃣ Navigate to Action Mappings...'); await page.goto('http://100.81.138.77:8081/#/action-mappings', { waitUntil: 'networkidle', timeout: 60000 }); await page.waitForTimeout(2000); console.log('\n3️⃣ Download existing mappings...'); for (let i = 0; i < 3; i++) { await page.keyboard.press('Tab'); await page.waitForTimeout(300); } await page.keyboard.press('Enter'); await page.waitForTimeout(5000); console.log('\n4️⃣ Edit first mapping...'); await page.keyboard.press('Tab'); await page.waitForTimeout(300); await page.keyboard.press('Enter'); await page.waitForTimeout(2000); console.log('\n5️⃣ Modify name (add SYNC_TEST suffix)...'); await page.keyboard.press('End'); await page.waitForTimeout(200); await page.keyboard.type(' SYNC_TEST', { delay: 50 }); await page.waitForTimeout(500); await page.screenshot({ path: 'sync-verify-1-name-modified.png', fullPage: true }); console.log('\n6️⃣ Save changes (mark as dirty)...'); for (let i = 0; i < 10; i++) { await page.keyboard.press('Tab'); await page.waitForTimeout(200); } await page.keyboard.press('Enter'); await page.waitForTimeout(3000); console.log('\n7️⃣ Trigger sync to server...'); await page.keyboard.press('Escape'); await page.waitForTimeout(500); // Click sync button in toolbar await page.keyboard.press('Tab'); await page.waitForTimeout(300); await page.keyboard.press('Tab'); await page.waitForTimeout(300); await page.keyboard.press('Enter'); console.log(' Waiting for sync operation...'); await page.waitForTimeout(8000); await page.screenshot({ path: 'sync-verify-2-after-sync.png', fullPage: true }); } catch (error) { console.error('\n💥 TEST ERROR:', error.message); await page.screenshot({ path: 'sync-verify-error.png', fullPage: true }); } console.log('\n' + '='.repeat(70)); console.log('SYNC VERIFICATION RESULTS'); console.log('='.repeat(70)); if (syncError) { console.log(`\n❌ SYNC FAILED`); console.log(` Error: ${syncError}`); } else if (syncSuccess) { console.log(`\n✅ SYNC SUCCESSFUL`); console.log(` PUT request completed successfully`); console.log(` Action mapping updated on server`); } else { console.log(`\n⚠️ SYNC STATUS UNCLEAR`); console.log(` Check screenshots for details`); } if (apiCalls.length > 0) { console.log(`\n📊 API Calls Made: ${apiCalls.length}`); apiCalls.forEach((call, i) => { console.log(` ${i + 1}. ${call.method} ${call.url}`); }); } await page.waitForTimeout(3000); await browser.close(); const exitCode = syncError ? 1 : 0; console.log(`\nExit code: ${exitCode}`); console.log('='.repeat(70)); process.exit(exitCode); })();