fix: mount /apps and docker socket in PR workflow build-and-deploy-ci job #41
@@ -17,8 +17,7 @@ module.exports = {
|
|||||||
|
|
||||||
// Format options
|
// Format options
|
||||||
format: [
|
format: [
|
||||||
process.env.CI ? 'progress' : 'progress-bar',
|
process.env.CI ? 'progress' : ['pretty', 'html:cucumber-report.html']
|
||||||
'pretty:cucumber-pretty'
|
|
||||||
],
|
],
|
||||||
|
|
||||||
// Output directory for reports
|
// Output directory for reports
|
||||||
|
|||||||
@@ -253,13 +253,13 @@ test.describe('Elo Rating Updates', () => {
|
|||||||
|
|
||||||
// Wait for page to load and tournaments to be fetched
|
// Wait for page to load and tournaments to be fetched
|
||||||
await page.waitForLoadState('domcontentloaded');
|
await page.waitForLoadState('domcontentloaded');
|
||||||
await page.waitForTimeout(2000);
|
await page.waitForTimeout(500);
|
||||||
|
|
||||||
// Wait for tournament dropdown to be ready
|
// Wait for tournament dropdown to be ready
|
||||||
await page.waitForSelector('select#tournament', { timeout: 5000 });
|
await page.waitForSelector('select#tournament', { timeout: 3000 });
|
||||||
|
|
||||||
// Wait a bit for tournaments to load
|
// Wait a bit for tournaments to load
|
||||||
await page.waitForTimeout(2000);
|
await page.waitForTimeout(500);
|
||||||
|
|
||||||
// Select the tournament manually
|
// Select the tournament manually
|
||||||
const tournamentSelect = await page.locator('select#tournament');
|
const tournamentSelect = await page.locator('select#tournament');
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ test.describe.serial('Epic 4: Tournament Creation', () => {
|
|||||||
await page.click('button[type="submit"]');
|
await page.click('button[type="submit"]');
|
||||||
|
|
||||||
// Wait for redirect to admin or player profile (indicates successful login)
|
// Wait for redirect to admin or player profile (indicates successful login)
|
||||||
await page.waitForURL(/\/(admin|players)/, { timeout: 10000 });
|
await page.waitForURL(/\/(admin|players)/, { timeout: 5000 });
|
||||||
|
|
||||||
// Navigate to new tournament page
|
// Navigate to new tournament page
|
||||||
await page.goto('/admin/tournaments/new');
|
await page.goto('/admin/tournaments/new');
|
||||||
@@ -106,20 +106,23 @@ test.describe.serial('Epic 4: Tournament Creation', () => {
|
|||||||
await page.click('button[type="submit"]');
|
await page.click('button[type="submit"]');
|
||||||
|
|
||||||
// Wait for redirect to admin or player profile (indicates successful login)
|
// Wait for redirect to admin or player profile (indicates successful login)
|
||||||
await page.waitForURL(/\/(admin|players)/, { timeout: 10000 });
|
await page.waitForURL(/\/(admin|players)/, { timeout: 5000 });
|
||||||
|
|
||||||
await page.goto('/admin/tournaments/new');
|
await page.goto('/admin/tournaments/new');
|
||||||
|
|
||||||
// Wait for step 1 form to load
|
// Wait for step 1 form to load
|
||||||
await page.waitForSelector('input[name="name"]', { timeout: 10000 });
|
await page.waitForSelector('input[name="name"]', { timeout: 5000 });
|
||||||
|
|
||||||
// Check for required fields on Step 1
|
// 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();
|
||||||
|
|
||||||
|
// Fill in the required name field first so Next actually advances
|
||||||
|
await page.fill('input[name="name"]', 'Test Tournament');
|
||||||
|
|
||||||
// Step through to Step 2 to check for submit button (only appears after clicking Next)
|
// Step through to Step 2 to check for submit button (only appears after clicking Next)
|
||||||
await page.click('button:has-text("Next")');
|
await page.click('button:has-text("Next")');
|
||||||
await page.waitForSelector('button[type="submit"]', { timeout: 10000 });
|
await page.waitForSelector('button[type="submit"]', { timeout: 5000 });
|
||||||
await expect(page.locator('button[type="submit"]')).toBeVisible();
|
await expect(page.locator('button[type="submit"]')).toBeVisible();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -131,7 +134,7 @@ test.describe.serial('Epic 4: Tournament Creation', () => {
|
|||||||
await page.click('button[type="submit"]');
|
await page.click('button[type="submit"]');
|
||||||
|
|
||||||
// Wait for redirect to admin or player profile (indicates successful login)
|
// Wait for redirect to admin or player profile (indicates successful login)
|
||||||
await page.waitForURL(/\/(admin|players)/, { timeout: 10000 });
|
await page.waitForURL(/\/(admin|players)/, { timeout: 5000 });
|
||||||
|
|
||||||
// Navigate to new tournament page
|
// Navigate to new tournament page
|
||||||
await page.goto('/admin/tournaments/new');
|
await page.goto('/admin/tournaments/new');
|
||||||
|
|||||||
@@ -133,7 +133,7 @@ test.describe.serial('Issue #7: Schedule Tab', () => {
|
|||||||
await page.fill('input[name="email"]', testEmail);
|
await page.fill('input[name="email"]', testEmail);
|
||||||
await page.fill('input[name="password"]', testPassword);
|
await page.fill('input[name="password"]', testPassword);
|
||||||
await page.click('button[type="submit"]');
|
await page.click('button[type="submit"]');
|
||||||
await page.waitForURL(/\/(admin|players)/, { timeout: 10000 });
|
await page.waitForURL(/\/(admin|players)/, { timeout: 5000 });
|
||||||
|
|
||||||
// Navigate to tournament detail
|
// Navigate to tournament detail
|
||||||
await page.goto(`/admin/tournaments/${tournamentId}`);
|
await page.goto(`/admin/tournaments/${tournamentId}`);
|
||||||
@@ -149,7 +149,7 @@ test.describe.serial('Issue #7: Schedule Tab', () => {
|
|||||||
await page.fill('input[name="email"]', testEmail);
|
await page.fill('input[name="email"]', testEmail);
|
||||||
await page.fill('input[name="password"]', testPassword);
|
await page.fill('input[name="password"]', testPassword);
|
||||||
await page.click('button[type="submit"]');
|
await page.click('button[type="submit"]');
|
||||||
await page.waitForURL(/\/(admin|players)/, { timeout: 10000 });
|
await page.waitForURL(/\/(admin|players)/, { timeout: 5000 });
|
||||||
|
|
||||||
// Navigate to schedule page
|
// Navigate to schedule page
|
||||||
await page.goto(`/admin/tournaments/${tournamentId}/schedule`);
|
await page.goto(`/admin/tournaments/${tournamentId}/schedule`);
|
||||||
@@ -166,7 +166,7 @@ test.describe.serial('Issue #7: Schedule Tab', () => {
|
|||||||
await page.fill('input[name="email"]', testEmail);
|
await page.fill('input[name="email"]', testEmail);
|
||||||
await page.fill('input[name="password"]', testPassword);
|
await page.fill('input[name="password"]', testPassword);
|
||||||
await page.click('button[type="submit"]');
|
await page.click('button[type="submit"]');
|
||||||
await page.waitForURL(/\/(admin|players)/, { timeout: 10000 });
|
await page.waitForURL(/\/(admin|players)/, { timeout: 5000 });
|
||||||
|
|
||||||
// Navigate to schedule page
|
// Navigate to schedule page
|
||||||
await page.goto(`/admin/tournaments/${tournamentId}/schedule`);
|
await page.goto(`/admin/tournaments/${tournamentId}/schedule`);
|
||||||
@@ -196,7 +196,7 @@ test.describe.serial('Issue #7: Schedule Tab', () => {
|
|||||||
await page.fill('input[name="email"]', testEmail);
|
await page.fill('input[name="email"]', testEmail);
|
||||||
await page.fill('input[name="password"]', testPassword);
|
await page.fill('input[name="password"]', testPassword);
|
||||||
await page.click('button[type="submit"]');
|
await page.click('button[type="submit"]');
|
||||||
await page.waitForURL(/\/(admin|players)/, { timeout: 10000 });
|
await page.waitForURL(/\/(admin|players)/, { timeout: 5000 });
|
||||||
|
|
||||||
// Navigate to schedule page
|
// Navigate to schedule page
|
||||||
await page.goto(`/admin/tournaments/${tournamentId}/schedule`);
|
await page.goto(`/admin/tournaments/${tournamentId}/schedule`);
|
||||||
@@ -218,7 +218,7 @@ test.describe.serial('Issue #7: Schedule Tab', () => {
|
|||||||
await page.fill('input[name="email"]', testEmail);
|
await page.fill('input[name="email"]', testEmail);
|
||||||
await page.fill('input[name="password"]', testPassword);
|
await page.fill('input[name="password"]', testPassword);
|
||||||
await page.click('button[type="submit"]');
|
await page.click('button[type="submit"]');
|
||||||
await page.waitForURL(/\/(admin|players)/, { timeout: 10000 });
|
await page.waitForURL(/\/(admin|players)/, { timeout: 5000 });
|
||||||
|
|
||||||
// Call the schedule API
|
// Call the schedule API
|
||||||
const response = await page.request.get(
|
const response = await page.request.get(
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ test.describe.serial('Issue #22: Team Configuration', () => {
|
|||||||
await page.fill('input[name="email"]', testEmail);
|
await page.fill('input[name="email"]', testEmail);
|
||||||
await page.fill('input[name="password"]', testPassword);
|
await page.fill('input[name="password"]', testPassword);
|
||||||
await page.click('button[type="submit"]');
|
await page.click('button[type="submit"]');
|
||||||
await page.waitForURL(/\/(admin|players)/, { timeout: 10000 });
|
await page.waitForURL(/\/(admin|players)/, { timeout: 5000 });
|
||||||
|
|
||||||
// Navigate to tournament creation
|
// Navigate to tournament creation
|
||||||
await page.goto('/admin/tournaments/new');
|
await page.goto('/admin/tournaments/new');
|
||||||
@@ -105,7 +105,7 @@ test.describe.serial('Issue #22: Team Configuration', () => {
|
|||||||
await page.fill('input[name="email"]', testEmail);
|
await page.fill('input[name="email"]', testEmail);
|
||||||
await page.fill('input[name="password"]', testPassword);
|
await page.fill('input[name="password"]', testPassword);
|
||||||
await page.click('button[type="submit"]');
|
await page.click('button[type="submit"]');
|
||||||
await page.waitForURL(/\/(admin|players)/, { timeout: 10000 });
|
await page.waitForURL(/\/(admin|players)/, { timeout: 5000 });
|
||||||
|
|
||||||
// Navigate to tournament creation
|
// Navigate to tournament creation
|
||||||
await page.goto('/admin/tournaments/new');
|
await page.goto('/admin/tournaments/new');
|
||||||
@@ -127,7 +127,7 @@ test.describe.serial('Issue #22: Team Configuration', () => {
|
|||||||
const playerName4 = `Player ${Date.now() + 3}`;
|
const playerName4 = `Player ${Date.now() + 3}`;
|
||||||
|
|
||||||
// Create first player - wait for search input to appear first
|
// Create first player - wait for search input to appear first
|
||||||
await page.waitForSelector('input[placeholder*="Search"]', { timeout: 10000 });
|
await page.waitForSelector('input[placeholder*="Search"]', { timeout: 5000 });
|
||||||
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`);
|
||||||
@@ -181,7 +181,7 @@ test.describe.serial('Issue #22: Team Configuration', () => {
|
|||||||
await page.fill('input[name="email"]', testEmail);
|
await page.fill('input[name="email"]', testEmail);
|
||||||
await page.fill('input[name="password"]', testPassword);
|
await page.fill('input[name="password"]', testPassword);
|
||||||
await page.click('button[type="submit"]');
|
await page.click('button[type="submit"]');
|
||||||
await page.waitForURL(/\/(admin|players)/, { timeout: 10000 });
|
await page.waitForURL(/\/(admin|players)/, { timeout: 5000 });
|
||||||
|
|
||||||
// Navigate to tournament creation
|
// Navigate to tournament creation
|
||||||
await page.goto('/admin/tournaments/new');
|
await page.goto('/admin/tournaments/new');
|
||||||
@@ -259,7 +259,7 @@ test.describe.serial('Issue #22: Team Configuration', () => {
|
|||||||
await page.fill('input[name="email"]', testEmail);
|
await page.fill('input[name="email"]', testEmail);
|
||||||
await page.fill('input[name="password"]', testPassword);
|
await page.fill('input[name="password"]', testPassword);
|
||||||
await page.click('button[type="submit"]');
|
await page.click('button[type="submit"]');
|
||||||
await page.waitForURL(/\/(admin|players)/, { timeout: 10000 });
|
await page.waitForURL(/\/(admin|players)/, { timeout: 5000 });
|
||||||
|
|
||||||
// Navigate to edit tournament page
|
// Navigate to edit tournament page
|
||||||
await page.goto(`/admin/tournaments/${tournamentId}/edit`);
|
await page.goto(`/admin/tournaments/${tournamentId}/edit`);
|
||||||
|
|||||||
@@ -11,11 +11,54 @@
|
|||||||
|
|
||||||
import { test, expect } from '@playwright/test';
|
import { test, expect } from '@playwright/test';
|
||||||
import { prisma } from '@/lib/prisma';
|
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: `allowties-admin-${timestamp}@example.com`,
|
||||||
|
password: 'AdminPassword123!',
|
||||||
|
name: `AllowTies Admin ${timestamp}`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
test.describe('Tournament Edit - allowTies functionality', () => {
|
test.describe('Tournament Edit - allowTies functionality', () => {
|
||||||
let tournamentId: number;
|
let tournamentId: number;
|
||||||
|
let testEmail: string;
|
||||||
|
let testPassword: string;
|
||||||
|
|
||||||
test.beforeAll(async () => {
|
test.beforeAll(async () => {
|
||||||
|
// Create admin user via API
|
||||||
|
const credentials = getTestCredentials();
|
||||||
|
testEmail = credentials.email;
|
||||||
|
testPassword = credentials.password;
|
||||||
|
|
||||||
|
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: credentials.name,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log('allowTies test user creation response:', response.status);
|
||||||
|
|
||||||
|
// Update user to club_admin role
|
||||||
|
const user = await prisma.user.findUnique({
|
||||||
|
where: { email: testEmail },
|
||||||
|
});
|
||||||
|
if (user) {
|
||||||
|
await prisma.user.update({
|
||||||
|
where: { id: user.id },
|
||||||
|
data: { role: 'club_admin' },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Create a test tournament for editing
|
// Create a test tournament for editing
|
||||||
const tournament = await prisma.event.create({
|
const tournament = await prisma.event.create({
|
||||||
data: {
|
data: {
|
||||||
@@ -25,6 +68,7 @@ test.describe('Tournament Edit - allowTies functionality', () => {
|
|||||||
status: 'planned',
|
status: 'planned',
|
||||||
allowTies: false,
|
allowTies: false,
|
||||||
targetScore: 5,
|
targetScore: 5,
|
||||||
|
ownerId: user?.id,
|
||||||
createdAt: new Date(),
|
createdAt: new Date(),
|
||||||
updatedAt: new Date(),
|
updatedAt: new Date(),
|
||||||
},
|
},
|
||||||
@@ -37,16 +81,28 @@ test.describe('Tournament Edit - allowTies functionality', () => {
|
|||||||
if (tournamentId) {
|
if (tournamentId) {
|
||||||
await prisma.event.delete({
|
await prisma.event.delete({
|
||||||
where: { id: tournamentId },
|
where: { id: tournamentId },
|
||||||
});
|
}).catch(() => {});
|
||||||
|
}
|
||||||
|
// Clean up user
|
||||||
|
const user = await prisma.user.findUnique({ where: { email: testEmail } });
|
||||||
|
if (user) {
|
||||||
|
await prisma.user.delete({ where: { id: user.id } });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should display allowTies checkbox on edit form @chromium-admin', async ({ page }) => {
|
test('should display allowTies checkbox on edit form @chromium-admin', 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"]');
|
||||||
|
await page.waitForURL(/\/(admin|players)/, { timeout: 5000 });
|
||||||
|
|
||||||
// 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 - edit page shows "Edit Tournament" heading
|
// Wait for form to load - edit page shows "Edit Tournament" heading
|
||||||
await expect(page.locator('text=Edit Tournament')).toBeVisible();
|
await expect(page.locator('text=Edit Tournament')).toBeVisible({ timeout: 5000 });
|
||||||
|
|
||||||
// Check that allowTies checkbox exists
|
// Check that allowTies checkbox exists
|
||||||
const allowTiesCheckbox = page.locator('input[name="allowTies"]');
|
const allowTiesCheckbox = page.locator('input[name="allowTies"]');
|
||||||
@@ -55,11 +111,18 @@ test.describe('Tournament Edit - allowTies functionality', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should save allowTies when toggled to true @chromium-admin', async ({ page }) => {
|
test('should save allowTies when toggled to true @chromium-admin', 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"]');
|
||||||
|
await page.waitForURL(/\/(admin|players)/, { timeout: 5000 });
|
||||||
|
|
||||||
// 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
|
||||||
await expect(page.locator('text=Edit Tournament')).toBeVisible();
|
await expect(page.locator('text=Edit Tournament')).toBeVisible({ timeout: 5000 });
|
||||||
|
|
||||||
// Toggle allowTies checkbox
|
// Toggle allowTies checkbox
|
||||||
const allowTiesCheckbox = page.locator('input[name="allowTies"]');
|
const allowTiesCheckbox = page.locator('input[name="allowTies"]');
|
||||||
@@ -87,11 +150,18 @@ test.describe('Tournament Edit - allowTies functionality', () => {
|
|||||||
data: { allowTies: true },
|
data: { allowTies: true },
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 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"]');
|
||||||
|
await page.waitForURL(/\/(admin|players)/, { timeout: 5000 });
|
||||||
|
|
||||||
// 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
|
||||||
await expect(page.locator('text=Edit Tournament')).toBeVisible();
|
await expect(page.locator('text=Edit Tournament')).toBeVisible({ timeout: 5000 });
|
||||||
|
|
||||||
// Verify checkbox is checked
|
// Verify checkbox is checked
|
||||||
const allowTiesCheckbox = page.locator('input[name="allowTies"]');
|
const allowTiesCheckbox = page.locator('input[name="allowTies"]');
|
||||||
|
|||||||
Reference in New Issue
Block a user