const { chromium } = require('playwright'); async function testBulkPage() { console.log('๐Ÿงช Starting Bulk Page Tests...\n'); const browser = await chromium.launch({ headless: false }); const context = await browser.newContext(); const page = await context.newPage(); const results = { passed: [], failed: [], warnings: [] }; try { // Navigate to bulk page console.log('๐Ÿ“ Navigating to /bulk page...'); await page.goto('http://localhost:3000/bulk', { waitUntil: 'networkidle' }); await page.waitForTimeout(2000); // Test 1: Check page loads console.log('โœ“ Test 1: Page loads successfully'); const title = await page.textContent('h1'); if (title.includes('Bulk Operations')) { results.passed.push('Page title correct'); } else { results.failed.push(`Page title incorrect: "${title}"`); } // Test 2: Check emulator selector console.log('โœ“ Test 2: Emulator selector exists'); const emulatorButtons = await page.$$('[class*="capitalize"]'); if (emulatorButtons.length === 4) { results.passed.push('All 4 emulator buttons present'); } else { results.failed.push(`Expected 4 emulator buttons, found ${emulatorButtons.length}`); } // Test 3: Check operation type buttons console.log('โœ“ Test 3: Operation type buttons'); const usersButton = await page.getByText('Users', { exact: false }); const furnitureButton = await page.getByText('Furniture', { exact: false }); const catalogButton = await page.getByText('Catalog', { exact: false }); if (await usersButton.count() > 0) { results.passed.push('Users operation type button found'); } else { results.failed.push('Users operation type button missing'); } // Test 4: Switch to Furniture operations console.log('โœ“ Test 4: Switching operation types'); await page.click('text=Furniture'); await page.waitForTimeout(1000); // Check if furniture actions are displayed const deleteAction = await page.getByText('Delete Items', { exact: false }); if (await deleteAction.count() > 0) { results.passed.push('Furniture operations load correctly'); } else { results.failed.push('Furniture operations failed to load'); } // Test 5: Switch to Catalog operations console.log('โœ“ Test 5: Catalog operations'); await page.click('text=Catalog'); await page.waitForTimeout(1000); const enableAction = await page.getByText('Enable Items', { exact: false }); if (await enableAction.count() > 0) { results.passed.push('Catalog operations load correctly'); } else { results.failed.push('Catalog operations failed to load'); } // Test 6: Check action selection console.log('โœ“ Test 6: Action selection'); await page.click('text=Update Price'); await page.waitForTimeout(500); // Check if parameter input appears const priceInput = await page.$('input[type="number"]'); if (priceInput) { results.passed.push('Action parameters display correctly'); } else { results.failed.push('Action parameters failed to display'); } // Test 7: Switch back to Users and check data loading console.log('โœ“ Test 7: Users data loading'); await page.click('text=Users'); await page.waitForTimeout(2000); // Wait for items to load or "No items found" message await page.waitForSelector('text=Select Items', { timeout: 5000 }); const itemsText = await page.textContent('text=Select Items'); const selectedCount = itemsText.match(/\((\d+) selected\)/); results.passed.push(`Users page loaded (${selectedCount ? selectedCount[1] : 0} items available)`); // Test 8: Search functionality console.log('โœ“ Test 8: Search functionality'); const searchInput = await page.$('input[placeholder*="Search"]'); if (searchInput) { await searchInput.fill('test'); await page.waitForTimeout(500); results.passed.push('Search input works'); } else { results.failed.push('Search input not found'); } // Test 9: Check select all button console.log('โœ“ Test 9: Select All button'); const selectAllButton = await page.getByText('Select All', { exact: false }); if (await selectAllButton.count() > 0) { results.passed.push('Select All button present'); } else { results.failed.push('Select All button missing'); } // Test 10: Check execute button state console.log('โœ“ Test 10: Execute button'); const executeButton = await page.$('button:has-text("Execute")'); if (executeButton) { const isDisabled = await executeButton.isDisabled(); if (isDisabled) { results.passed.push('Execute button correctly disabled when nothing selected'); } else { results.warnings.push('Execute button should be disabled when nothing selected'); } } else { results.failed.push('Execute button not found'); } // Test 11: Test API endpoint exists console.log('โœ“ Test 11: API endpoint check'); const apiResponse = await page.request.post('http://localhost:3000/api/bulk', { data: { type: 'users', action: 'give_credits', ids: [], params: { amount: 100 } } }); if (apiResponse.status() === 400) { results.passed.push('API endpoint exists and validates input'); } else { results.warnings.push(`API returned unexpected status: ${apiResponse.status()}`); } // Test 12: Check emulator switching console.log('โœ“ Test 12: Emulator switching'); await page.click('text=Kepler'); await page.waitForTimeout(1000); await page.click('text=Havana'); await page.waitForTimeout(1000); results.passed.push('Emulator switching works'); // Test 13: Check all user actions are present console.log('โœ“ Test 13: All user actions present'); await page.click('text=Users'); await page.waitForTimeout(500); const expectedActions = ['Ban Users', 'Unban Users', 'Give Credits', 'Give Pixels', 'Give Points', 'Set Rank']; let foundActions = 0; for (const action of expectedActions) { const elem = await page.getByText(action, { exact: false }); if (await elem.count() > 0) { foundActions++; } } if (foundActions === expectedActions.length) { results.passed.push(`All ${expectedActions.length} user actions present`); } else { results.failed.push(`Only ${foundActions}/${expectedActions.length} user actions found`); } } catch (error) { results.failed.push(`Test error: ${error.message}`); console.error('Test failed:', error); } finally { await browser.close(); } // Print results console.log('\n' + '='.repeat(50)); console.log('๐Ÿ“Š TEST RESULTS'); console.log('='.repeat(50)); console.log(`\nโœ… PASSED (${results.passed.length}):`); results.passed.forEach(msg => console.log(` โœ“ ${msg}`)); if (results.warnings.length > 0) { console.log(`\nโš ๏ธ WARNINGS (${results.warnings.length}):`); results.warnings.forEach(msg => console.log(` โš  ${msg}`)); } if (results.failed.length > 0) { console.log(`\nโŒ FAILED (${results.failed.length}):`); results.failed.forEach(msg => console.log(` โœ— ${msg}`)); } console.log('\n' + '='.repeat(50)); console.log(`Total: ${results.passed.length + results.warnings.length + results.failed.length} tests`); console.log('='.repeat(50) + '\n'); return results; } testBulkPage().catch(console.error);