|
| 1 | +import {test, expect} from "@playwright/test"; |
| 2 | + |
| 3 | +test.describe("States", () => { |
| 4 | + test.beforeEach(async ({context, page}) => { |
| 5 | + await context.clearCookies(); |
| 6 | + |
| 7 | + await page.goto("/"); |
| 8 | + await page.evaluate(() => { |
| 9 | + localStorage.clear(); |
| 10 | + sessionStorage.clear(); |
| 11 | + }); |
| 12 | + |
| 13 | + // Navigate with seed parameter and wait for full load |
| 14 | + await page.goto("/?seed=test-states&width=1280&height=720"); |
| 15 | + |
| 16 | + // Wait for map generation to complete |
| 17 | + await page.waitForFunction(() => (window as any).mapId !== undefined, {timeout: 60000}); |
| 18 | + |
| 19 | + // Additional wait for any rendering/animations to settle |
| 20 | + await page.waitForTimeout(500); |
| 21 | + }); |
| 22 | + |
| 23 | + test("removing a state via UI should allow military regeneration without errors", async ({page}) => { |
| 24 | + // First click the options trigger (►) to open the menu |
| 25 | + await page.click("#optionsTrigger"); |
| 26 | + await page.waitForTimeout(300); |
| 27 | + |
| 28 | + // Open the Tools tab |
| 29 | + await page.click("#toolsTab"); |
| 30 | + await page.waitForTimeout(200); |
| 31 | + |
| 32 | + // Click "States" button to open States Editor |
| 33 | + await page.click("#editStatesButton"); |
| 34 | + await page.waitForSelector("#statesEditor", {state: "visible", timeout: 5000}); |
| 35 | + await page.waitForTimeout(300); |
| 36 | + |
| 37 | + // Find a state row and get its ID |
| 38 | + const stateId = await page.evaluate(() => { |
| 39 | + const stateRow = document.querySelector("#statesBodySection > div[data-id]") as HTMLElement; |
| 40 | + return stateRow ? parseInt(stateRow.dataset.id!, 10) : null; |
| 41 | + }); |
| 42 | + |
| 43 | + expect(stateId).not.toBeNull(); |
| 44 | + |
| 45 | + // Verify this state is in neighbors of other states before removal |
| 46 | + const neighborsBefore = await page.evaluate((id: number) => { |
| 47 | + const {states} = (window as any).pack; |
| 48 | + return states.filter((s: any) => s.i && !s.removed && s.neighbors && s.neighbors.includes(id)).length; |
| 49 | + }, stateId!); |
| 50 | + |
| 51 | + // Click the trash icon to remove the state |
| 52 | + await page.click(`#statesBodySection > div[data-id="${stateId}"] .icon-trash-empty`); |
| 53 | + |
| 54 | + // Confirm the removal in the jQuery dialog - look for "Remove" button in the dialog buttonpane |
| 55 | + await page.waitForSelector(".ui-dialog:has(#alert) .ui-dialog-buttonpane", {state: "visible", timeout: 3000}); |
| 56 | + await page.click(".ui-dialog:has(#alert) .ui-dialog-buttonpane button:first-child"); // "Remove" is first button |
| 57 | + await page.waitForTimeout(500); |
| 58 | + |
| 59 | + // Verify the state is no longer in neighbors of any other state |
| 60 | + const neighborsAfter = await page.evaluate((id: number) => { |
| 61 | + const {states} = (window as any).pack; |
| 62 | + return states.filter((s: any) => s.i && !s.removed && s.neighbors && s.neighbors.includes(id)).length; |
| 63 | + }, stateId!); |
| 64 | + |
| 65 | + expect(neighborsAfter).toBe(0); |
| 66 | + |
| 67 | + // Close the States Editor - the close button is in the jQuery UI dialog wrapper |
| 68 | + await page.click(".ui-dialog:has(#statesEditor) .ui-dialog-titlebar-close"); |
| 69 | + await page.waitForTimeout(200); |
| 70 | + |
| 71 | + // Now click "Military" regenerate button and verify no errors |
| 72 | + await page.click("#regenerateMilitary"); |
| 73 | + await page.waitForTimeout(1000); |
| 74 | + |
| 75 | + // Verify military was regenerated without throwing |
| 76 | + const militaryResult = await page.evaluate(() => { |
| 77 | + const {states} = (window as any).pack; |
| 78 | + const validStates = states.filter((s: any) => s.i && !s.removed); |
| 79 | + // Check that at least some states have military data |
| 80 | + return { |
| 81 | + statesCount: validStates.length, |
| 82 | + statesWithMilitary: validStates.filter((s: any) => s.military && s.military.length > 0).length |
| 83 | + }; |
| 84 | + }); |
| 85 | + |
| 86 | + expect(militaryResult.statesCount).toBeGreaterThan(0); |
| 87 | + // At least some states should have military |
| 88 | + expect(militaryResult.statesWithMilitary).toBeGreaterThanOrEqual(0); |
| 89 | + }); |
| 90 | +}); |
0 commit comments