fix: mount /apps and docker socket in PR workflow build-and-deploy-ci job #41

Merged
david merged 33 commits from fix/switch-to-npm-ci into main 2026-05-20 19:51:36 +00:00
8 changed files with 59 additions and 30 deletions
Showing only changes of commit a0872d07ef - Show all commits
+10 -7
View File
@@ -13,6 +13,7 @@ import path from 'path';
test.describe('CSV Upload Player Deduplication', () => { test.describe('CSV Upload Player Deduplication', () => {
let testTournamentId: number; let testTournamentId: number;
const testPlayerIds: number[] = []; const testPlayerIds: number[] = [];
const ts = Date.now();
test.beforeAll(async () => { test.beforeAll(async () => {
// Create a test tournament // 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({ await prisma.player.deleteMany({
where: { where: {
name: { OR: [
contains: 'Dedupe', { 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 // First, create some players manually to simulate previous uploads
const player1 = await prisma.player.create({ const player1 = await prisma.player.create({
data: { data: {
name: 'Aggregate Test', name: `Aggregate Test ${ts}`,
normalizedName: 'aggregate test', normalizedName: `aggregate test ${ts}`,
currentElo: 1050, currentElo: 1050,
gamesPlayed: 5, gamesPlayed: 5,
wins: 3, wins: 3,
@@ -175,7 +178,7 @@ test.describe('CSV Upload Player Deduplication', () => {
// Upload a CSV with the same player name // 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 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'); const csvPath = path.join(__dirname, 'temp-aggregate-test.csv');
fs.writeFileSync(csvPath, csvContent); fs.writeFileSync(csvPath, csvContent);
+1 -1
View File
@@ -17,7 +17,7 @@ module.exports = {
// Format options // Format options
format: [ format: [
'progress-bar', process.env.CI ? 'progress' : 'progress-bar',
'pretty:cucumber-pretty' 'pretty:cucumber-pretty'
], ],
+30 -12
View File
@@ -13,24 +13,33 @@ import path from 'path';
test.describe('Elo Rating Updates', () => { test.describe('Elo Rating Updates', () => {
test.beforeAll(async () => { test.beforeAll(async () => {
// Clean up any existing test data // Clean up any existing test data
const playerIds = await getEloTestPlayerIds();
// First delete matches that reference players // First delete matches that reference players
await prisma.match.deleteMany({ await prisma.match.deleteMany({
where: { where: {
OR: [ OR: [
{ player1P1Id: { in: await getEloTestPlayerIds() } }, { player1P1Id: { in: playerIds } },
{ player1P2Id: { in: await getEloTestPlayerIds() } }, { player1P2Id: { in: playerIds } },
{ player2P1Id: { in: await getEloTestPlayerIds() } }, { player2P1Id: { in: playerIds } },
{ player2P2Id: { in: await getEloTestPlayerIds() } }, { player2P2Id: { in: playerIds } },
] ]
} }
}); });
// Then delete event participants that reference players
await prisma.eventParticipant.deleteMany({
where: {
playerId: { in: playerIds }
}
});
// Then delete partnerships // Then delete partnerships
await prisma.partnershipStat.deleteMany({ await prisma.partnershipStat.deleteMany({
where: { where: {
OR: [ OR: [
{ player1Id: { in: await getEloTestPlayerIds() } }, { player1Id: { in: playerIds } },
{ player2Id: { in: await getEloTestPlayerIds() } }, { player2Id: { in: playerIds } },
] ]
} }
}); });
@@ -47,24 +56,33 @@ test.describe('Elo Rating Updates', () => {
test.afterAll(async () => { test.afterAll(async () => {
// Clean up test data // Clean up test data
const playerIds = await getEloTestPlayerIds();
// First delete matches that reference players // First delete matches that reference players
await prisma.match.deleteMany({ await prisma.match.deleteMany({
where: { where: {
OR: [ OR: [
{ player1P1Id: { in: await getEloTestPlayerIds() } }, { player1P1Id: { in: playerIds } },
{ player1P2Id: { in: await getEloTestPlayerIds() } }, { player1P2Id: { in: playerIds } },
{ player2P1Id: { in: await getEloTestPlayerIds() } }, { player2P1Id: { in: playerIds } },
{ player2P2Id: { in: await getEloTestPlayerIds() } }, { player2P2Id: { in: playerIds } },
] ]
} }
}); });
// Then delete event participants that reference players
await prisma.eventParticipant.deleteMany({
where: {
playerId: { in: playerIds }
}
});
// Then delete partnerships // Then delete partnerships
await prisma.partnershipStat.deleteMany({ await prisma.partnershipStat.deleteMany({
where: { where: {
OR: [ OR: [
{ player1Id: { in: await getEloTestPlayerIds() } }, { player1Id: { in: playerIds } },
{ player2Id: { in: await getEloTestPlayerIds() } }, { player2Id: { in: playerIds } },
] ]
} }
}); });
+2 -2
View File
@@ -17,8 +17,8 @@ test.describe('Epic 3: Rankings Page', () => {
test('Rankings page loads and displays rankings table', async ({ page }) => { test('Rankings page loads and displays rankings table', async ({ page }) => {
await page.goto('/rankings'); await page.goto('/rankings');
// Check page title or heading // Check page title or heading - use .first() since page may have both h1 and h2
await expect(page.locator('h1, h2')).toContainText(/rankings?/i); await expect(page.locator('h1, h2').first()).toContainText(/rankings?/i);
// Check for rankings table // Check for rankings table
await expect(page.locator('table')).toBeVisible(); await expect(page.locator('table')).toBeVisible();
+8 -1
View File
@@ -110,9 +110,16 @@ test.describe.serial('Epic 4: Tournament Creation', () => {
await page.goto('/admin/tournaments/new'); 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('input[name="name"]')).toBeVisible();
await expect(page.locator('select[name="format"]')).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(); await expect(page.locator('button[type="submit"]')).toBeVisible();
}); });
+2 -2
View File
@@ -138,8 +138,8 @@ test.describe.serial('Issue #7: Schedule Tab', () => {
// Navigate to tournament detail // Navigate to tournament detail
await page.goto(`/admin/tournaments/${tournamentId}`); await page.goto(`/admin/tournaments/${tournamentId}`);
// Check Schedule tab link exists // Check Schedule tab link exists - use button since page uses buttons for tabs
const scheduleLink = page.locator('a', { hasText: 'Schedule' }); const scheduleLink = page.locator('button', { hasText: 'Schedule' });
await expect(scheduleLink).toBeVisible(); await expect(scheduleLink).toBeVisible();
}); });
+2 -1
View File
@@ -126,7 +126,8 @@ test.describe.serial('Issue #22: Team Configuration', () => {
const playerName3 = `Player ${Date.now() + 2}`; const playerName3 = `Player ${Date.now() + 2}`;
const playerName4 = `Player ${Date.now() + 3}`; 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.fill('input[placeholder*="Search"]', playerName1);
await page.waitForTimeout(500); await page.waitForTimeout(500);
await page.click(`text=+ Create "${playerName1}" as new player`); await page.click(`text=+ Create "${playerName1}" as new player`);
+4 -4
View File
@@ -45,8 +45,8 @@ test.describe('Tournament Edit - allowTies functionality', () => {
// Navigate to tournament edit page // Navigate to tournament edit page
await page.goto(`/admin/tournaments/${tournamentId}/edit`); await page.goto(`/admin/tournaments/${tournamentId}/edit`);
// Wait for form to load // Wait for form to load - edit page shows "Edit Tournament" heading
await expect(page.locator('text=Tournament Name')).toBeVisible(); await expect(page.locator('text=Edit Tournament')).toBeVisible();
// Check that allowTies checkbox exists // Check that allowTies checkbox exists
const allowTiesCheckbox = page.locator('input[name="allowTies"]'); const allowTiesCheckbox = page.locator('input[name="allowTies"]');
@@ -59,7 +59,7 @@ test.describe('Tournament Edit - allowTies functionality', () => {
await page.goto(`/admin/tournaments/${tournamentId}/edit`); await page.goto(`/admin/tournaments/${tournamentId}/edit`);
// Wait for form to load // Wait for form to load
await expect(page.locator('text=Tournament Name')).toBeVisible(); await expect(page.locator('text=Edit Tournament')).toBeVisible();
// Toggle allowTies checkbox // Toggle allowTies checkbox
const allowTiesCheckbox = page.locator('input[name="allowTies"]'); const allowTiesCheckbox = page.locator('input[name="allowTies"]');
@@ -91,7 +91,7 @@ test.describe('Tournament Edit - allowTies functionality', () => {
await page.goto(`/admin/tournaments/${tournamentId}/edit`); await page.goto(`/admin/tournaments/${tournamentId}/edit`);
// Wait for form to load // 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 // Verify checkbox is checked
const allowTiesCheckbox = page.locator('input[name="allowTies"]'); const allowTiesCheckbox = page.locator('input[name="allowTies"]');