a0872d07ef
- cucumber: use 'progress' formatter in CI (not progress-bar TTY) - csv-upload: use timestamp in player names to avoid unique constraint - elo-ratings: delete event_participants before players (FK constraint) - epic3-rankings: use .first() on h1/h2 locator (strict mode) - schedule-tab: look for button instead of anchor for Schedule tab - team-config: wait for search input before filling (step 2 async) - tournament-edit-allowTies: check for 'Edit Tournament' not 'Tournament Name' - epic4-tournament-creation: submit button only on step 2, add waitForSelector
158 lines
5.0 KiB
TypeScript
158 lines
5.0 KiB
TypeScript
/**
|
|
* Epic 4: Tournament Management
|
|
* Acceptance Test: Tournament Creation
|
|
*
|
|
* User Story: As a tournament admin, I want to create a new tournament so that I can organize events
|
|
*
|
|
* Acceptance Criteria:
|
|
* - Tournament creation form
|
|
* - Fields: Name, Format (round-robin, single elim, double elim, Swiss), Date, Status
|
|
* - Default settings for each format
|
|
* - Validation for required fields
|
|
*/
|
|
|
|
import { test, expect } from '@playwright/test';
|
|
import { prisma } from '@/lib/prisma';
|
|
const BASE_URL = process.env.CI ? 'https://euchre-ci.notsosm.art' : 'http://localhost:3000';
|
|
|
|
|
|
function getTestCredentials() {
|
|
const timestamp = Date.now();
|
|
return {
|
|
email: `admin-${timestamp}@example.com`,
|
|
password: 'AdminPassword123!',
|
|
name: `Admin User ${timestamp}`
|
|
};
|
|
}
|
|
|
|
test.describe.serial('Epic 4: Tournament Creation', () => {
|
|
let testEmail: string;
|
|
let testPassword: string;
|
|
let testName: string;
|
|
|
|
test.beforeAll(async () => {
|
|
const credentials = getTestCredentials();
|
|
testEmail = credentials.email;
|
|
testPassword = credentials.password;
|
|
testName = credentials.name;
|
|
|
|
// Create admin user via API
|
|
const response = await fetch(`${BASE_URL}/api/auth/sign-up/email`, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'Origin': BASE_URL
|
|
},
|
|
body: JSON.stringify({
|
|
email: testEmail,
|
|
password: testPassword,
|
|
name: testName
|
|
})
|
|
});
|
|
|
|
console.log('Tournament test user creation response:', response.status);
|
|
const data = await response.json();
|
|
console.log('Tournament test user data:', data);
|
|
|
|
// Update user to club_admin role
|
|
const user = await prisma.user.findUnique({
|
|
where: { email: testEmail }
|
|
});
|
|
console.log('Found user for tournament test:', user ? 'yes' : 'no');
|
|
if (user) {
|
|
await prisma.user.update({
|
|
where: { id: user.id },
|
|
data: { role: 'club_admin' }
|
|
});
|
|
console.log('Updated user role to club_admin');
|
|
}
|
|
});
|
|
|
|
test.afterAll(async () => {
|
|
try {
|
|
const user = await prisma.user.findUnique({
|
|
where: { email: testEmail }
|
|
});
|
|
if (user) {
|
|
await prisma.user.delete({ where: { id: user.id } });
|
|
}
|
|
} catch (error) {
|
|
console.error('Cleanup error:', error);
|
|
}
|
|
});
|
|
|
|
test('Tournament creation page exists and loads', async ({ page }) => {
|
|
// Login first
|
|
await page.goto('/auth/login');
|
|
await page.fill('input[name="email"]', testEmail);
|
|
await page.fill('input[name="password"]', testPassword);
|
|
await page.click('button[type="submit"]');
|
|
|
|
// Wait for redirect to admin or player profile (indicates successful login)
|
|
await page.waitForURL(/\/(admin|players)/, { timeout: 10000 });
|
|
|
|
// Navigate to new tournament page
|
|
await page.goto('/admin/tournaments/new');
|
|
|
|
// Check for form
|
|
await expect(page.locator('form')).toBeVisible();
|
|
});
|
|
|
|
test('Tournament form has required fields', async ({ page }) => {
|
|
// Login first
|
|
await page.goto('/auth/login');
|
|
await page.fill('input[name="email"]', testEmail);
|
|
await page.fill('input[name="password"]', testPassword);
|
|
await page.click('button[type="submit"]');
|
|
|
|
// Wait for redirect to admin or player profile (indicates successful login)
|
|
await page.waitForURL(/\/(admin|players)/, { timeout: 10000 });
|
|
|
|
await page.goto('/admin/tournaments/new');
|
|
|
|
// 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();
|
|
});
|
|
|
|
test('Create tournament with valid data', async ({ page }) => {
|
|
// Login first
|
|
await page.goto('/auth/login');
|
|
await page.fill('input[name="email"]', testEmail);
|
|
await page.fill('input[name="password"]', testPassword);
|
|
await page.click('button[type="submit"]');
|
|
|
|
// Wait for redirect to admin or player profile (indicates successful login)
|
|
await page.waitForURL(/\/(admin|players)/, { timeout: 10000 });
|
|
|
|
// Navigate to new tournament page
|
|
await page.goto('/admin/tournaments/new');
|
|
|
|
const tournamentName = `Test Tournament ${Date.now()}`;
|
|
|
|
// Fill form
|
|
await page.fill('input[name="name"]', tournamentName);
|
|
await page.selectOption('select[name="format"]', 'round_robin');
|
|
|
|
// Submit form
|
|
await page.click('button[type="submit"]');
|
|
|
|
// Wait for redirect to tournament list
|
|
await page.waitForURL('**/admin/tournaments**', { timeout: 10000 });
|
|
|
|
// Verify tournament was created in database
|
|
const tournament = await prisma.event.findFirst({
|
|
where: { name: tournamentName }
|
|
});
|
|
expect(tournament).not.toBeNull();
|
|
});
|
|
});
|