From 6e7def68af0273a982f6bc8c177bfd976288d905 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Fri, 12 Jun 2026 01:15:04 +0200 Subject: [PATCH 1/3] Update tournament-pairings.spec.ts --- test/tournament-pairings.spec.ts | 82 ++++++++++++++++++-------------- 1 file changed, 46 insertions(+), 36 deletions(-) diff --git a/test/tournament-pairings.spec.ts b/test/tournament-pairings.spec.ts index df7b5172..5e101e46 100644 --- a/test/tournament-pairings.spec.ts +++ b/test/tournament-pairings.spec.ts @@ -266,6 +266,7 @@ test.describe('Tournament Pairing Creation', () => { const idA = completePairing.tournamentCompetitor0!._id; const idB = completePairing.tournamentCompetitor1!._id; + const table = ((completePairing.table ?? 0) + 1).toString(); await page.goto(`/tournaments/${tournamentId}`); @@ -274,59 +275,68 @@ test.describe('Tournament Pairing Creation', () => { await page.getByRole('menuitem', { name: 'Configure Round 2' }).click(); await page.waitForURL(`/tournaments/${tournamentId}/pairings`); - // Dialog auto-opens with all round-0 participants pre-selected: + // Dialog auto-opens — dismiss it to proceed with manual pairing: const generateDialog = page.getByRole('dialog', { name: 'Auto-Generate Pairings' }); await expect(generateDialog).toBeVisible(); - - // All round-0 participants (24 competitors → 12 pairings) should be pre-selected: - await generateDialog.getByLabel('Table Count').fill('12'); - await generateDialog.getByRole('button', { name: 'Generate' }).click(); + await page.keyboard.press('Escape'); await expect(generateDialog).not.toBeVisible(); + // With no previous round, all competitors appear in the excluded area: + const excludedArea = page.getByRole('heading', { name: 'Excluded' }).locator('../..'); + + // Expect included area to have no rows: const rows = page.getByTestId('pairing-item'); - await expect(rows).toHaveCount(12); + await expect(rows).toHaveCount(0); + // Create a pairing: + const addButton = page.getByRole('button', { name: 'Add Pairing Slot' }); + await addButton.click(); + await expect(rows).toHaveCount(1); + + // Drag idA and idB into it: const gripFor = (id: string): Locator => page.locator(`[aria-roledescription="draggable"][data-competitor-id="${id}"]`); + await dragTo(page, gripFor(idA), rows.nth(0).locator('[data-over]').nth(0)); + await dragTo(page, gripFor(idB), rows.nth(0).locator('[data-over]').nth(1)); - const excludedDroppable = page.getByRole('heading', { name: 'Excluded' }).locator('..').locator('[data-over]'); + // Observe repeat match up error: + await expect(rows.nth(0).locator('[data-color="red"]')).toBeVisible(); - // Add a new pairing slot: - const newRowIndex = await rows.count(); - await page.getByRole('button', { name: 'Add Pairing Slot' }).click(); - const newRow = rows.nth(newRowIndex); + // Replace idB with next unpaired competitor by dragging it onto side B: + await dragTo( + page, + excludedArea.locator('[aria-roledescription="draggable"]').first(), + rows.nth(0).locator('[data-over]').nth(1), + ); + await expect(rows.nth(0).locator('[data-color="green"]')).toBeVisible(); + + // Set table to completePairing.table: + await rows.nth(0).getByRole('combobox', { name: 'Table Assignment' }).click(); + await page.getByRole('option', { name: table, exact: true }).click(); - // ---- Repeat opponent → red ---- - // Drag idA and idB from their generated rows into the new empty slot: - await dragTo(page, gripFor(idA), newRow.locator('[data-over]').nth(0)); - await dragTo(page, gripFor(idB), newRow.locator('[data-over]').nth(1)); - await expect(newRow.locator('[data-color="red"]')).toBeVisible(); + // Observe repeat table warning: + await expect(rows.nth(0).locator('[data-color="yellow"]')).toBeVisible(); - // ---- Repeat table → yellow ---- - // Move idB back to excluded, replace with a third competitor (first available from remaining rows): + // Create another pairing: + await addButton.click(); + await expect(rows).toHaveCount(2); + + // Fill the next pairing by dragging 2 competitors into the slots: await dragTo( page, - newRow.locator('[aria-roledescription="draggable"]').nth(1), - excludedDroppable, + excludedArea.locator('[aria-roledescription="draggable"]').first(), + rows.nth(1).locator('[data-over]').nth(0), ); await dragTo( page, - page.locator(`[aria-roledescription="draggable"]:not([data-competitor-id="${idA}"]):not([data-competitor-id="${idB}"])`).first(), - newRow.locator('[data-over]').nth(1), + excludedArea.locator('[aria-roledescription="draggable"]').first(), + rows.nth(1).locator('[data-over]').nth(1), ); + + // Set table to completePairing.table: + await rows.nth(1).getByRole('combobox', { name: 'Table Assignment' }).click(); + await page.getByRole('option', { name: table, exact: true }).click(); - // Assign a table idA played in round 0 (tables are assigned starting at stored value 1, - // displayed as "2" since the dropdown labels are value + 1): - await newRow.getByRole('combobox', { name: 'Table Assignment' }).click(); - await page.getByRole('option', { name: '2', exact: true }).click(); - await expect(newRow.locator('[data-color="yellow"]')).toBeVisible(); - - // ---- Duplicate table → both red ---- - const lastRowIndex = await rows.count(); - await page.getByRole('button', { name: 'Add Pairing Slot' }).click(); - const lastRow = rows.nth(lastRowIndex); - await lastRow.getByRole('combobox', { name: 'Table Assignment' }).click(); - await page.getByRole('option', { name: '2', exact: true }).click(); - await expect(newRow.locator('[data-color="red"]')).toBeVisible(); - await expect(lastRow.locator('[data-color="red"]')).toBeVisible(); + // Observer double-assigned table error: + await expect(rows.nth(1).locator('[data-color="red"]')).toBeVisible(); }); }); From 62b0d47352a927bd88959fc0af859a72aa75946f Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Fri, 12 Jun 2026 01:22:52 +0200 Subject: [PATCH 2/3] Update tournament-pairings.spec.ts --- test/tournament-pairings.spec.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/test/tournament-pairings.spec.ts b/test/tournament-pairings.spec.ts index 5e101e46..0b081385 100644 --- a/test/tournament-pairings.spec.ts +++ b/test/tournament-pairings.spec.ts @@ -261,12 +261,15 @@ test.describe('Tournament Pairing Creation', () => { (p) => p.tournamentCompetitor0 && p.tournamentCompetitor1, ); if (!completePairing) { - throw new Error('No complete round 0 pairing found'); + throw new Error('No complete round 0 pairing found!'); } const idA = completePairing.tournamentCompetitor0!._id; const idB = completePairing.tournamentCompetitor1!._id; - const table = ((completePairing.table ?? 0) + 1).toString(); + if (completePairing.table === null) { + throw new Error('Complete round 0 pairing has no table assigned!'); + } + const table = (completePairing.table + 1).toString(); await page.goto(`/tournaments/${tournamentId}`); From 964cb891d8fc1cb05aacb737d85e38eb08c32dd8 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Fri, 12 Jun 2026 01:25:31 +0200 Subject: [PATCH 3/3] Update tournament-pairings.spec.ts --- test/tournament-pairings.spec.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/test/tournament-pairings.spec.ts b/test/tournament-pairings.spec.ts index 0b081385..b8548462 100644 --- a/test/tournament-pairings.spec.ts +++ b/test/tournament-pairings.spec.ts @@ -258,7 +258,7 @@ test.describe('Tournament Pairing Creation', () => { round: 0, }); const completePairing = round0Pairings.find( - (p) => p.tournamentCompetitor0 && p.tournamentCompetitor1, + (p) => p.tournamentCompetitor0 && p.tournamentCompetitor1 && p.table !== null, ); if (!completePairing) { throw new Error('No complete round 0 pairing found!'); @@ -266,10 +266,7 @@ test.describe('Tournament Pairing Creation', () => { const idA = completePairing.tournamentCompetitor0!._id; const idB = completePairing.tournamentCompetitor1!._id; - if (completePairing.table === null) { - throw new Error('Complete round 0 pairing has no table assigned!'); - } - const table = (completePairing.table + 1).toString(); + const table = (completePairing.table! + 1).toString(); await page.goto(`/tournaments/${tournamentId}`);