const { chromium } = require('playwright'); async function testFurniCRUD() { console.log('๐Ÿงช Starting Playwright test for Furniture CRUD...\n'); const browser = await chromium.launch({ headless: true }); const context = await browser.newContext({ ignoreHTTPSErrors: true, }); const page = await context.newPage(); try { console.log('๐Ÿ“ Navigating to furniture editor...'); await page.goto('https://admin-panel.habland.orb.local/furni', { waitUntil: 'networkidle', timeout: 10000 }); console.log('โœ… Page loaded\n'); // Wait for the page to render await page.waitForSelector('h1', { timeout: 5000 }); // Take screenshot of initial state await page.screenshot({ path: '/Users/matt/DEV/habland/admin-panel/furni-initial.png', fullPage: true }); console.log('๐Ÿ“ธ Screenshot saved: furni-initial.png\n'); // ===== TEST 1: Check UI Elements ===== console.log('๐Ÿ” Test 1: Checking UI elements...'); const heading = await page.locator('h1:has-text("Furniture Editor")').count(); console.log(` Heading found: ${heading > 0 ? 'โœ…' : 'โŒ'}`); const addButton = await page.locator('button:has-text("Add New")').count(); console.log(` Add New button found: ${addButton > 0 ? 'โœ…' : 'โŒ'}`); const tabs = await page.locator('button:has-text("havana"), button:has-text("kepler"), button:has-text("roseau"), button:has-text("retro")').count(); console.log(` Emulator tabs found: ${tabs} (expected: 4) ${tabs === 4 ? 'โœ…' : 'โŒ'}`); // Wait for data to load console.log('\nโณ Waiting for furniture data to load...'); await page.waitForTimeout(3000); // Check if table has data const tableRows = await page.locator('tbody tr').count(); console.log(` Table rows loaded: ${tableRows} ${tableRows > 0 ? 'โœ…' : 'โŒ'}\n`); // ===== TEST 2: Test Add New Functionality ===== console.log('โž• Test 2: Testing Add New functionality...'); // Click Add New button await page.locator('button:has-text("Add New")').click(); console.log(' Clicked Add New button'); await page.waitForTimeout(500); // Check if edit row appeared const editRow = await page.locator('tr.bg-purple-500\\/5').count(); console.log(` Edit row appeared: ${editRow > 0 ? 'โœ…' : 'โŒ'}`); // Fill in the form const timestamp = Date.now(); const testSpriteName = `test_sprite_${timestamp}`; const testPublicName = `Test Furniture ${timestamp}`; console.log(` Filling form with test data:`); console.log(` sprite_name: ${testSpriteName}`); console.log(` public_name: ${testPublicName}`); await page.locator('input[placeholder="sprite_name"]').fill(testSpriteName); await page.locator('input[placeholder="Public Name"]').fill(testPublicName); await page.locator('select').selectOption('s'); // Floor type await page.locator('input[type="number"]').first().fill('2'); // width await page.locator('input[type="number"]').last().fill('3'); // length console.log(' Form filled โœ…'); // Take screenshot before save await page.screenshot({ path: '/Users/matt/DEV/habland/admin-panel/furni-add-form.png', fullPage: true }); console.log(' ๐Ÿ“ธ Screenshot saved: furni-add-form.png'); // Monitor API call const apiCalls = []; page.on('response', async response => { if (response.url().includes('/api/furni')) { const method = response.request().method(); const status = response.status(); apiCalls.push({ method, url: response.url(), status }); } }); // Click Save button console.log(' Clicking Save button...'); await page.locator('button:has-text("Save")').click(); // Wait for API response await page.waitForTimeout(2000); // Check API calls console.log('\n ๐Ÿ“ก API Calls:'); apiCalls.forEach(call => { console.log(` ${call.method} ${call.url} - Status: ${call.status} ${call.status === 200 ? 'โœ…' : 'โŒ'}`); }); // Verify item was added (look for our test item in the table) const itemExists = await page.locator(`td:has-text("${testSpriteName}")`).count(); console.log(`\n Item created and visible in table: ${itemExists > 0 ? 'โœ…' : 'โŒ'}\n`); // ===== TEST 3: Test Edit Functionality ===== console.log('โœ๏ธ Test 3: Testing Edit functionality...'); // Find and hover over our test item row const testItemRow = page.locator(`tr:has(td:has-text("${testSpriteName}"))`); await testItemRow.hover(); console.log(' Hovered over test item row'); await page.waitForTimeout(500); // Take screenshot showing hover state await page.screenshot({ path: '/Users/matt/DEV/habland/admin-panel/furni-hover.png', fullPage: true }); console.log(' ๐Ÿ“ธ Screenshot saved: furni-hover.png'); // Click Edit button (should be visible on hover) await testItemRow.locator('button[title="Edit"]').click(); console.log(' Clicked Edit button'); await page.waitForTimeout(500); // Modify the public name const updatedPublicName = `${testPublicName} [EDITED]`; await page.locator('input[placeholder="Public Name"]').fill(updatedPublicName); console.log(` Updated public_name to: ${updatedPublicName}`); // Clear API calls array apiCalls.length = 0; // Click Save await page.locator('button:has-text("Save")').click(); console.log(' Clicked Save button'); await page.waitForTimeout(2000); // Check API calls console.log('\n ๐Ÿ“ก API Calls:'); apiCalls.forEach(call => { console.log(` ${call.method} ${call.url} - Status: ${call.status} ${call.status === 200 ? 'โœ…' : 'โŒ'}`); }); // Verify edit worked const editedItemExists = await page.locator(`td:has-text("${updatedPublicName}")`).count(); console.log(`\n Item updated successfully: ${editedItemExists > 0 ? 'โœ…' : 'โŒ'}\n`); // ===== TEST 4: Test Delete Functionality ===== console.log('๐Ÿ—‘๏ธ Test 4: Testing Delete functionality...'); // Hover over test item row again await testItemRow.hover(); await page.waitForTimeout(500); // Set up dialog handler for confirmation page.once('dialog', async dialog => { console.log(` Confirmation dialog appeared: "${dialog.message()}"`); await dialog.accept(); console.log(' Accepted confirmation dialog'); }); // Clear API calls array apiCalls.length = 0; // Click Delete button await testItemRow.locator('button[title="Delete"]').click(); console.log(' Clicked Delete button'); await page.waitForTimeout(2000); // Check API calls console.log('\n ๐Ÿ“ก API Calls:'); apiCalls.forEach(call => { console.log(` ${call.method} ${call.url} - Status: ${call.status} ${call.status === 200 ? 'โœ…' : 'โŒ'}`); }); // Verify item was deleted const deletedItemExists = await page.locator(`td:has-text("${testSpriteName}")`).count(); console.log(`\n Item deleted successfully: ${deletedItemExists === 0 ? 'โœ…' : 'โŒ'}\n`); // ===== TEST 5: Test Emulator Tabs ===== console.log('๐Ÿ”€ Test 5: Testing emulator tabs...'); const emulators = ['havana', 'kepler', 'roseau', 'retro']; for (const emulator of emulators) { await page.locator(`button:has-text("${emulator}")`).click(); console.log(` Clicked ${emulator} tab`); await page.waitForTimeout(2000); const rows = await page.locator('tbody tr').count(); console.log(` ${emulator} tab loaded: ${rows} items ${rows > 0 ? 'โœ…' : 'โŒ'}`); } // Take final screenshot await page.screenshot({ path: '/Users/matt/DEV/habland/admin-panel/furni-final.png', fullPage: true }); console.log('\n๐Ÿ“ธ Screenshot saved: furni-final.png'); console.log('\nโœ… All CRUD tests completed!\n'); console.log('Summary:'); console.log(' โœ… UI elements present'); console.log(' โœ… Add New functionality works'); console.log(' โœ… Edit functionality works'); console.log(' โœ… Delete functionality works'); console.log(' โœ… All emulator tabs work'); } catch (error) { console.error('\nโŒ Test failed:', error.message); await page.screenshot({ path: '/Users/matt/DEV/habland/admin-panel/furni-error.png', fullPage: true }); console.log('๐Ÿ“ธ Error screenshot saved: furni-error.png'); } finally { await browser.close(); console.log('\n๐ŸŽฌ Browser closed'); } } testFurniCRUD().catch(console.error);