Merge branch 'bugfix/7-tournament-schedule-tests': Schedule generation, clickable matchups, and test fixes
Release / release (push) Failing after 11s

Resolved conflict in common-steps.ts by combining player schedule step definitions
(from bugfix/9 merge) with tournament schedule step definitions (from bugfix/7).
This commit is contained in:
2026-05-01 18:25:25 -07:00
15 changed files with 844 additions and 76 deletions
+132 -25
View File
@@ -108,16 +108,10 @@ Given('I am logged in as a player', async function () {
/**
* Precondition: I am logged in as a tournament admin
* Note: In the actual app, admin roles are assigned by club admins or via API.
* For acceptance tests, we'll use the default player role and test admin features
* as the dev site would handle them.
* For acceptance tests, we'll assign the tournament_admin role directly via Prisma.
*/
Given('I am logged in as a tournament admin', async function () {
console.log('🌍 Creating and logging in as a player (tournament admin role is assigned via UI/API)...');
// For now, use the same flow as player
// In real usage, the admin would either:
// 1. Be pre-created on the dev site
// 2. Have role assigned via API
// 3. Use the admin dashboard to manage users
console.log('🌍 Creating and logging in as a tournament admin...');
const credentials = generateTestCredentials();
world.user = credentials;
@@ -133,6 +127,34 @@ Given('I am logged in as a tournament admin', async function () {
// Wait for redirect
await world.page.waitForURL(/\/players\/\d+\/profile/, { timeout: 15000 });
// Extract user ID from the URL (e.g., /players/2147/profile)
const currentUrl = world.page.url();
const match = currentUrl.match(/\/players\/(\d+)\/profile/);
if (match) {
const playerId = match[1];
world.playerId = playerId;
// Get the user ID from the database
const prisma = await world.getPrisma();
const player = await prisma.player.findUnique({
where: { id: parseInt(playerId) },
include: { user: true }
});
if (player && player.user) {
const userId = player.user.id;
(world.user as any).id = userId;
console.log(`🌍 User ID extracted: ${userId}`);
// Assign tournament_admin role to the user
await prisma.user.update({
where: { id: userId },
data: { role: 'tournament_admin' }
});
console.log(`🌍 Assigned tournament_admin role to user: ${userId}`);
}
}
console.log(`🌍 User created: ${credentials.email}`);
});
@@ -408,19 +430,42 @@ Given('a tournament exists with {int} teams', async function (teamCount: number)
// Get Prisma client
const prisma = await world.getPrisma();
const timestamp = Date.now();
// Find or create a tournament
let tournament = await prisma.event.findFirst({
orderBy: { createdAt: 'desc' },
// Get the current user ID for ownership
const userId = world.user?.id;
if (!userId) {
throw new Error('User ID not found. Ensure user is logged in before creating tournament.');
}
// Always create a new tournament for test isolation
const tournament = await prisma.event.create({
data: {
name: `Test Tournament ${timestamp}`,
createdAt: new Date(),
ownerId: userId, // Set the owner to the current user
},
});
if (!tournament) {
// Create a new tournament if none exists
const timestamp = Date.now();
tournament = await prisma.event.create({
// Euchre is 2v2, so each team has 2 players
// Create teamCount * 2 players and add them as participants
const playerCount = teamCount * 2;
for (let i = 1; i <= playerCount; i++) {
const player = await prisma.player.create({
data: {
name: `Test Tournament ${timestamp}`,
createdAt: new Date(),
name: `Tournament Player ${i} ${timestamp}`,
normalizedName: `tournament player ${i} ${timestamp}`,
currentElo: 1000,
gamesPlayed: 0,
wins: 0,
losses: 0,
},
});
await prisma.eventParticipant.create({
data: {
eventId: tournament.id,
playerId: player.id,
},
});
}
@@ -428,23 +473,85 @@ Given('a tournament exists with {int} teams', async function (teamCount: number)
world.tournament = tournament;
world.tournamentTeamCount = teamCount;
console.log(`🌍 Using tournament: ${tournament.name} (ID: ${tournament.id})`);
console.log(`🌍 Created tournament: ${tournament.name} (ID: ${tournament.id}) with ${playerCount} players (${teamCount} teams)`);
});
When('I go to the tournament schedule page', async function () {
console.log('🌍 Going to tournament schedule page');
const tournamentId = world.tournament?.id || 1;
await world.page.goto(`${world.baseURL}/admin/tournaments/${tournamentId}/schedule`);
await world.page.waitForLoadState('domcontentloaded');
await world.page.waitForLoadState('load');
// Wait for client components to hydrate
await world.page.waitForTimeout(1000);
});
Given('a tournament has a generated schedule', async function () {
console.log('🌍 Note: Tournament schedule requires generation via API or UI');
console.log('🌍 For acceptance tests, this would be created before running the test');
// In a real test run, we would:
// 1. Create a tournament
// 2. Add teams/participants
// 3. Generate schedule via API or UI
console.log('🌍 Creating tournament with generated schedule');
const prisma = await world.getPrisma();
const timestamp = Date.now();
// Get the current user ID for ownership
const userId = world.user?.id;
if (!userId) {
throw new Error('User ID not found. Ensure user is logged in before creating tournament.');
}
// Create a tournament
const tournament = await prisma.event.create({
data: {
name: `Test Schedule Tournament ${timestamp}`,
createdAt: new Date(),
ownerId: userId, // Set the owner to the current user
},
});
// Create 4 players and add them as participants
const players = [];
for (let i = 1; i <= 4; i++) {
const player = await prisma.player.create({
data: {
name: `Schedule Player ${i} ${timestamp}`,
normalizedName: `schedule player ${i} ${timestamp}`,
currentElo: 1000,
gamesPlayed: 0,
wins: 0,
losses: 0,
},
});
players.push(player);
await prisma.eventParticipant.create({
data: {
eventId: tournament.id,
playerId: player.id,
},
});
}
// Generate schedule via API
const response = await fetch(`${world.baseURL}/api/tournaments/${tournament.id}/schedule`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
});
if (!response.ok) {
console.log('🌍 Failed to generate schedule:', response.status, response.statusText);
// Try to get error details
try {
const errorData = await response.json();
console.log('🌍 Error details:', errorData);
} catch {
// Ignore
}
} else {
const data = await response.json();
console.log('🌍 Schedule generated:', data);
}
world.tournament = tournament;
world.tournamentTeamCount = 4;
console.log(`🌍 Tournament with schedule created: ${tournament.name} (ID: ${tournament.id})`);
});
Given('there are recent activities in the system', async function () {