import { test, expect } from '@playwright/test'; import { DP2FormPage } from './utils/page-objects'; import { TestDataFactory, TestScenario } from './utils/test-data'; test.describe('DP2 Form - Basic Functionality', () => { let formPage: DP2FormPage; test.beforeEach(async ({ page }) => { formPage = new DP2FormPage(page); await formPage.goto(); }); test('should load the form correctly', async () => { await expect(formPage.playerNameInput).toBeVisible(); await expect(formPage.currentPointsInput).toBeVisible(); await expect(formPage.calculateButton).toBeVisible(); }); test('should show crime category buttons', async () => { for (const [key, button] of Object.entries(formPage.crimeCategoryButtons)) { await expect(button).toBeVisible(); } }); test('should filter crimes by category', async ({ page }) => { // Test item offenses await formPage.selectCrimeCategory('item'); const itemOptions = await formPage.specificOffenseSelect.locator('option').allTextContents(); expect(itemOptions.length).toBeGreaterThan(0); expect(itemOptions.some(option => option.includes('Theft') || option.includes('Killing'))).toBe(true); // Test block offenses await formPage.selectCrimeCategory('block'); const blockOptions = await formPage.specificOffenseSelect.locator('option').allTextContents(); expect(blockOptions.length).toBeGreaterThan(0); expect(blockOptions.some(option => option.includes('Grief') || option.includes('Vandalism'))).toBe(true); // Test hacking offenses await formPage.selectCrimeCategory('hacking'); const hackingOptions = await formPage.specificOffenseSelect.locator('option').allTextContents(); expect(hackingOptions.length).toBeGreaterThan(0); expect(hackingOptions.some(option => option.includes('X-Ray') || option.includes('Hacking'))).toBe(true); // Test communication offenses await formPage.selectCrimeCategory('communication'); const commOptions = await formPage.specificOffenseSelect.locator('option').allTextContents(); expect(commOptions.length).toBeGreaterThan(0); expect(commOptions.some(option => option.includes('Abusive') || option.includes('Manipulation'))).toBe(true); }); test('should show offense details section when crime is selected', async () => { await formPage.selectCrimeCategory('item'); await formPage.selectSpecificOffense('theft'); await expect(formPage.offenseDetailsSection).toBeVisible(); }); test('should show special items section for theft', async () => { await formPage.selectCrimeCategory('item'); await formPage.selectSpecificOffense('theft'); // Check that special item inputs are visible for (const [key, input] of Object.entries(formPage.specialItems)) { await expect(input).toBeVisible(); } }); test('should show block count input for grief', async () => { await formPage.selectCrimeCategory('block'); await formPage.selectSpecificOffense('grief'); await expect(formPage.blockCountInput).toBeVisible(); }); test('should show SPP checkbox for applicable crimes', async () => { await formPage.selectCrimeCategory('block'); await formPage.selectSpecificOffense('trespassing_staff'); await expect(formPage.sppCheckbox).toBeVisible(); }); test('should allow adding additional items for theft', async () => { await formPage.selectCrimeCategory('item'); await formPage.selectSpecificOffense('theft'); await formPage.addAdditionalItem('diamond_sword', 3); // Verify the item was added const itemRows = formPage.additionalItemInputs.locator('div.flex.items-center.gap-2'); await expect(itemRows).toHaveCount(1); const inputs = itemRows.locator('input'); await expect(inputs.nth(0)).toHaveValue('diamond_sword'); await expect(inputs.nth(1)).toHaveValue('3'); }); test('should validate required fields', async () => { await formPage.calculateButton.click(); // Should not show results without required fields await expect(formPage.resultsSection).not.toBeVisible(); }); test('should reset form correctly', async () => { await formPage.fillPlayerInfo('TestPlayer', 10); await formPage.selectCrimeCategory('item'); await formPage.selectSpecificOffense('theft'); await formPage.calculatePunishment(); await formPage.waitForResults(); await formPage.resetForm(); // Form should be cleared await expect(formPage.playerNameInput).toHaveValue(''); await expect(formPage.currentPointsInput).toHaveValue('0'); await expect(formPage.resultsSection).not.toBeVisible(); }); }); test.describe('DP2 Form - Calculation Tests', () => { let formPage: DP2FormPage; test.beforeEach(async ({ page }) => { formPage = new DP2FormPage(page); await formPage.goto(); }); // Test all scenarios from our test data factory const scenarios = TestDataFactory.getAllScenarios(); for (const scenario of scenarios) { test(`should calculate ${scenario.offense.crimeId} correctly for ${scenario.player.name}`, async () => { // Skip empty form validation test if (scenario.player.name === '' && scenario.offense.crimeId === '') { return; } // Fill player info await formPage.fillPlayerInfo(scenario.player.name, scenario.player.currentPoints); // Determine category and select crime const crimeCategory = getCrimeCategory(scenario.offense.crimeId); await formPage.selectCrimeCategory(crimeCategory); await formPage.selectSpecificOffense(scenario.offense.crimeId); // Fill offense-specific details if (scenario.offense.specialItems) { await formPage.fillSpecialItems(scenario.offense.specialItems); } if (scenario.offense.itemDetails) { for (const item of scenario.offense.itemDetails) { await formPage.addAdditionalItem(item.type, item.quantity); } } if (scenario.offense.blockCount !== undefined) { await formPage.fillBlockCount(scenario.offense.blockCount); } if (scenario.offense.entityCount !== undefined) { await formPage.fillEntityCount(scenario.offense.entityCount); } if (scenario.offense.isSPP !== undefined) { await formPage.setSPP(scenario.offense.isSPP); } // Calculate and wait for results await formPage.calculatePunishment(); await formPage.waitForResults(); // Verify results if (scenario.expected.hasCommands) { const summary = await formPage.getSummaryValues(); // Note: These expectations may need adjustment based on actual implementation // For now, we just verify that results are generated expect(summary).toBeDefined(); expect(summary.crime).toBeDefined(); expect(summary.totalPoints).toBeDefined(); expect(summary.punishment).toBeDefined(); } }); } }); // Helper function to determine crime category function getCrimeCategory(crimeId: string): 'all' | 'item' | 'block' | 'hacking' | 'communication' { // This is a simplified mapping - in real implementation, you'd import CRIMES from dp2-rules const categoryMap: { [key: string]: 'item' | 'block' | 'hacking' | 'communication' } = { 'theft': 'item', 'unconsensual_killing': 'item', 'illegal_item_use': 'item', 'inappropriate_item_names': 'item', 'inappropriate_book_contents': 'item', 'vandalism': 'block', 'grief': 'block', 'theft_grief': 'block', 'vandalism_infrastructure': 'block', 'trespassing': 'block', 'trespassing_staff': 'block', 'x_raying': 'hacking', 'hacking_client': 'hacking', 'lagging_server': 'hacking', 'worldedit_misuse': 'hacking', 'exploit_abuse': 'hacking', 'abusive_chat': 'communication', 'inciting_verbal_conflict': 'communication', 'abusive_vc': 'communication', 'lying_to_staff': 'communication', 'manipulation': 'communication', 'grand_manipulation': 'communication', 'slander': 'communication', 'violation_nca': 'communication', }; return categoryMap[crimeId] || 'all'; }