Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 48 additions & 38 deletions test/tournament-pairings.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -258,14 +258,15 @@ 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');
throw new Error('No complete round 0 pairing found!');
}

const idA = completePairing.tournamentCompetitor0!._id;
const idB = completePairing.tournamentCompetitor1!._id;
const table = (completePairing.table! + 1).toString();

await page.goto(`/tournaments/${tournamentId}`);

Expand All @@ -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();
});
});
Loading