diff --git a/e2e/csv-upload-deduplication.test.ts b/e2e/csv-upload-deduplication.test.ts index 8210985..7c48736 100644 --- a/e2e/csv-upload-deduplication.test.ts +++ b/e2e/csv-upload-deduplication.test.ts @@ -13,6 +13,7 @@ import path from 'path'; test.describe('CSV Upload Player Deduplication', () => { let testTournamentId: number; const testPlayerIds: number[] = []; + const ts = Date.now(); test.beforeAll(async () => { // Create a test tournament @@ -47,12 +48,14 @@ test.describe('CSV Upload Player Deduplication', () => { }); } - // Delete test players (those with "Dedupe" in the name) + // Delete test players (those with "Dedupe" or "Aggregate Test" in the name) await prisma.player.deleteMany({ where: { - name: { - contains: 'Dedupe', - }, + OR: [ + { name: { contains: 'Dedupe' } }, + { name: { contains: 'Aggregate Test' } }, + { name: { contains: 'Whitespace' } }, + ], }, }); @@ -163,8 +166,8 @@ test.describe('CSV Upload Player Deduplication', () => { // First, create some players manually to simulate previous uploads const player1 = await prisma.player.create({ data: { - name: 'Aggregate Test', - normalizedName: 'aggregate test', + name: `Aggregate Test ${ts}`, + normalizedName: `aggregate test ${ts}`, currentElo: 1050, gamesPlayed: 5, wins: 3, @@ -175,7 +178,7 @@ test.describe('CSV Upload Player Deduplication', () => { // Upload a CSV with the same player name const csvContent = `Event #,Round,Table,Seat 1,Seat 3,Odds Points,Seat 2,Seat 4,Evens Points -1,1,1,Aggregate Test,Test Player 1,5,Test Player 2,Test Player 3,3`; +1,1,1,Aggregate Test ${ts},Test Player 1,5,Test Player 2,Test Player 3,3`; const csvPath = path.join(__dirname, 'temp-aggregate-test.csv'); fs.writeFileSync(csvPath, csvContent); diff --git a/e2e/cucumber/cucumber.config.ts b/e2e/cucumber/cucumber.config.ts index dac5d35..7a9a6c1 100644 --- a/e2e/cucumber/cucumber.config.ts +++ b/e2e/cucumber/cucumber.config.ts @@ -17,7 +17,7 @@ module.exports = { // Format options format: [ - 'progress-bar', + process.env.CI ? 'progress' : 'progress-bar', 'pretty:cucumber-pretty' ], diff --git a/e2e/elo-ratings.test.ts b/e2e/elo-ratings.test.ts index e41b152..06855b8 100644 --- a/e2e/elo-ratings.test.ts +++ b/e2e/elo-ratings.test.ts @@ -13,24 +13,33 @@ import path from 'path'; test.describe('Elo Rating Updates', () => { test.beforeAll(async () => { // Clean up any existing test data + const playerIds = await getEloTestPlayerIds(); + // First delete matches that reference players await prisma.match.deleteMany({ where: { OR: [ - { player1P1Id: { in: await getEloTestPlayerIds() } }, - { player1P2Id: { in: await getEloTestPlayerIds() } }, - { player2P1Id: { in: await getEloTestPlayerIds() } }, - { player2P2Id: { in: await getEloTestPlayerIds() } }, + { player1P1Id: { in: playerIds } }, + { player1P2Id: { in: playerIds } }, + { player2P1Id: { in: playerIds } }, + { player2P2Id: { in: playerIds } }, ] } }); + // Then delete event participants that reference players + await prisma.eventParticipant.deleteMany({ + where: { + playerId: { in: playerIds } + } + }); + // Then delete partnerships await prisma.partnershipStat.deleteMany({ where: { OR: [ - { player1Id: { in: await getEloTestPlayerIds() } }, - { player2Id: { in: await getEloTestPlayerIds() } }, + { player1Id: { in: playerIds } }, + { player2Id: { in: playerIds } }, ] } }); @@ -47,24 +56,33 @@ test.describe('Elo Rating Updates', () => { test.afterAll(async () => { // Clean up test data + const playerIds = await getEloTestPlayerIds(); + // First delete matches that reference players await prisma.match.deleteMany({ where: { OR: [ - { player1P1Id: { in: await getEloTestPlayerIds() } }, - { player1P2Id: { in: await getEloTestPlayerIds() } }, - { player2P1Id: { in: await getEloTestPlayerIds() } }, - { player2P2Id: { in: await getEloTestPlayerIds() } }, + { player1P1Id: { in: playerIds } }, + { player1P2Id: { in: playerIds } }, + { player2P1Id: { in: playerIds } }, + { player2P2Id: { in: playerIds } }, ] } }); + // Then delete event participants that reference players + await prisma.eventParticipant.deleteMany({ + where: { + playerId: { in: playerIds } + } + }); + // Then delete partnerships await prisma.partnershipStat.deleteMany({ where: { OR: [ - { player1Id: { in: await getEloTestPlayerIds() } }, - { player2Id: { in: await getEloTestPlayerIds() } }, + { player1Id: { in: playerIds } }, + { player2Id: { in: playerIds } }, ] } }); diff --git a/e2e/epic3-rankings.test.ts b/e2e/epic3-rankings.test.ts index c678104..03a0741 100644 --- a/e2e/epic3-rankings.test.ts +++ b/e2e/epic3-rankings.test.ts @@ -17,8 +17,8 @@ test.describe('Epic 3: Rankings Page', () => { test('Rankings page loads and displays rankings table', async ({ page }) => { await page.goto('/rankings'); - // Check page title or heading - await expect(page.locator('h1, h2')).toContainText(/rankings?/i); + // Check page title or heading - use .first() since page may have both h1 and h2 + await expect(page.locator('h1, h2').first()).toContainText(/rankings?/i); // Check for rankings table await expect(page.locator('table')).toBeVisible(); diff --git a/e2e/epic4-tournament-creation.test.ts b/e2e/epic4-tournament-creation.test.ts index bc223cf..cf78718 100644 --- a/e2e/epic4-tournament-creation.test.ts +++ b/e2e/epic4-tournament-creation.test.ts @@ -110,9 +110,16 @@ test.describe.serial('Epic 4: Tournament Creation', () => { await page.goto('/admin/tournaments/new'); - // Check for required fields + // Wait for step 1 form to load + await page.waitForSelector('input[name="name"]', { timeout: 10000 }); + + // Check for required fields on Step 1 await expect(page.locator('input[name="name"]')).toBeVisible(); await expect(page.locator('select[name="format"]')).toBeVisible(); + + // Step through to Step 2 to check for submit button (only appears after clicking Next) + await page.click('button:has-text("Next")'); + await page.waitForSelector('button[type="submit"]', { timeout: 10000 }); await expect(page.locator('button[type="submit"]')).toBeVisible(); }); diff --git a/e2e/schedule-tab.test.ts b/e2e/schedule-tab.test.ts index e7bef21..1dcd494 100644 --- a/e2e/schedule-tab.test.ts +++ b/e2e/schedule-tab.test.ts @@ -138,8 +138,8 @@ test.describe.serial('Issue #7: Schedule Tab', () => { // Navigate to tournament detail await page.goto(`/admin/tournaments/${tournamentId}`); - // Check Schedule tab link exists - const scheduleLink = page.locator('a', { hasText: 'Schedule' }); + // Check Schedule tab link exists - use button since page uses buttons for tabs + const scheduleLink = page.locator('button', { hasText: 'Schedule' }); await expect(scheduleLink).toBeVisible(); }); diff --git a/e2e/team-configuration.test.ts b/e2e/team-configuration.test.ts index b30b564..47abc5f 100644 --- a/e2e/team-configuration.test.ts +++ b/e2e/team-configuration.test.ts @@ -126,7 +126,8 @@ test.describe.serial('Issue #22: Team Configuration', () => { const playerName3 = `Player ${Date.now() + 2}`; const playerName4 = `Player ${Date.now() + 3}`; - // Create first player + // Create first player - wait for search input to appear first + await page.waitForSelector('input[placeholder*="Search"]', { timeout: 10000 }); await page.fill('input[placeholder*="Search"]', playerName1); await page.waitForTimeout(500); await page.click(`text=+ Create "${playerName1}" as new player`); diff --git a/e2e/tournament-edit-allowTies.test.ts b/e2e/tournament-edit-allowTies.test.ts index 8719e5f..c7ea63c 100644 --- a/e2e/tournament-edit-allowTies.test.ts +++ b/e2e/tournament-edit-allowTies.test.ts @@ -45,8 +45,8 @@ test.describe('Tournament Edit - allowTies functionality', () => { // Navigate to tournament edit page await page.goto(`/admin/tournaments/${tournamentId}/edit`); - // Wait for form to load - await expect(page.locator('text=Tournament Name')).toBeVisible(); + // Wait for form to load - edit page shows "Edit Tournament" heading + await expect(page.locator('text=Edit Tournament')).toBeVisible(); // Check that allowTies checkbox exists const allowTiesCheckbox = page.locator('input[name="allowTies"]'); @@ -59,7 +59,7 @@ test.describe('Tournament Edit - allowTies functionality', () => { await page.goto(`/admin/tournaments/${tournamentId}/edit`); // Wait for form to load - await expect(page.locator('text=Tournament Name')).toBeVisible(); + await expect(page.locator('text=Edit Tournament')).toBeVisible(); // Toggle allowTies checkbox const allowTiesCheckbox = page.locator('input[name="allowTies"]'); @@ -91,7 +91,7 @@ test.describe('Tournament Edit - allowTies functionality', () => { await page.goto(`/admin/tournaments/${tournamentId}/edit`); // Wait for form to load - await expect(page.locator('text=Tournament Name')).toBeVisible(); + await expect(page.locator('text=Edit Tournament')).toBeVisible(); // Verify checkbox is checked const allowTiesCheckbox = page.locator('input[name="allowTies"]');