perf: parallelize tests and reduce timeouts
Pull Request / unit-tests (pull_request) Successful in 2m3s
Pull Request / analyze-bump-type (pull_request) Successful in 13s
Pull Request / build-and-deploy-ci (pull_request) Failing after 16m0s

- Increase workers from 1 to 10 in CI for parallel execution
- Reduce expect timeout from 5000ms to 2000ms
- Reduce all waitForTimeout calls >1000ms to 200-500ms
- Remove unnecessary waits in global setup
This commit is contained in:
2026-05-19 00:39:46 -07:00
parent 005cf7293d
commit 38771a86cb
8 changed files with 22 additions and 26 deletions
+1 -1
View File
@@ -74,7 +74,7 @@ test.describe.serial('Account Lifecycle Acceptance Test', () => {
await page.waitForURL(/\/players\/\d+\/profile/, { timeout: 10000 }); await page.waitForURL(/\/players\/\d+\/profile/, { timeout: 10000 });
// Wait a moment for the user to be saved to database // Wait a moment for the user to be saved to database
await page.waitForTimeout(1000); await page.waitForTimeout(200);
// Verify user was created in database // Verify user was created in database
const user = await prisma.user.findUnique({ const user = await prisma.user.findUnique({
+6 -6
View File
@@ -315,7 +315,7 @@ ${tournament.id},2,1,${player1.name},${player3.name},10,${player2.name},${player
await page.click('button[type="submit"]'); await page.click('button[type="submit"]');
// Wait for upload to complete // Wait for upload to complete
await page.waitForTimeout(3000); await page.waitForTimeout(1000);
// Check for any error messages // Check for any error messages
const uploadContentAfter = await page.content(); const uploadContentAfter = await page.content();
@@ -328,11 +328,11 @@ ${tournament.id},2,1,${player1.name},${player3.name},10,${player2.name},${player
// Navigate back to upload page for second match // Navigate back to upload page for second match
await page.goto('/admin/matches/upload'); await page.goto('/admin/matches/upload');
await page.waitForLoadState('domcontentloaded'); await page.waitForLoadState('domcontentloaded');
await page.waitForTimeout(2000); await page.waitForTimeout(500);
// Re-select the tournament for the second upload // Re-select the tournament for the second upload
await page.waitForSelector('select#tournament', { timeout: 5000 }); await page.waitForSelector('select#tournament', { timeout: 3000 });
await page.waitForTimeout(1000); // Wait for tournaments to load await page.waitForTimeout(200); // Wait for tournaments to load
const tournamentSelect2 = await page.locator('select#tournament'); const tournamentSelect2 = await page.locator('select#tournament');
const currentSelection = await tournamentSelect2.inputValue(); const currentSelection = await tournamentSelect2.inputValue();
@@ -351,10 +351,10 @@ ${tournament.id},2,1,${player1.name},${player3.name},10,${player2.name},${player
await page.setInputFiles('input[type="file"]', tmpFile2); await page.setInputFiles('input[type="file"]', tmpFile2);
await page.waitForTimeout(500); await page.waitForTimeout(500);
await page.click('button[type="submit"]'); await page.click('button[type="submit"]');
await page.waitForTimeout(2000); await page.waitForTimeout(500);
fs.unlinkSync(tmpFile2); fs.unlinkSync(tmpFile2);
await page.waitForTimeout(2000); await page.waitForTimeout(500);
// Verify ratings after multiple matches // Verify ratings after multiple matches
const updatedPlayer1 = await prisma.player.findUnique({ const updatedPlayer1 = await prisma.player.findUnique({
+1 -1
View File
@@ -133,7 +133,7 @@ test.describe.serial('Epic 1: User Logout', () => {
await page.waitForLoadState('domcontentloaded'); await page.waitForLoadState('domcontentloaded');
// Wait a moment for the navigation component to update // Wait a moment for the navigation component to update
await page.waitForTimeout(1000); await page.waitForTimeout(200);
// Debug: Check what's on the page // Debug: Check what's on the page
const pageContent = await page.content(); const pageContent = await page.content();
+1 -1
View File
@@ -89,7 +89,7 @@ test.describe.serial('Epic 1: User Registration', () => {
}); });
// Wait a moment for JavaScript to be ready // Wait a moment for JavaScript to be ready
await page.waitForTimeout(1000); await page.waitForTimeout(200);
// Submit form // Submit form
const [response] = await Promise.all([ const [response] = await Promise.all([
+5 -5
View File
@@ -101,14 +101,14 @@ async function createTestUsers(config: FullConfig) {
try { try {
await page.waitForResponse(response => await page.waitForResponse(response =>
response.url().includes('/api/auth/sign-up/email') && response.status() === 200, response.url().includes('/api/auth/sign-up/email') && response.status() === 200,
{ timeout: 10000 } { timeout: 5000 }
); );
console.log('Sign-up API call successful'); console.log('Sign-up API call successful');
} catch { } catch {
console.log('Sign-up API call failed or timed out'); console.log('Sign-up API call failed or timed out');
} }
await page.waitForTimeout(2000); await page.waitForTimeout(500);
await context.storageState({ path: authFile }); await context.storageState({ path: authFile });
console.log(`Created and authenticated test user: ${testEmail}`); console.log(`Created and authenticated test user: ${testEmail}`);
@@ -133,14 +133,14 @@ async function createTestUsers(config: FullConfig) {
try { try {
await page.waitForResponse(response => await page.waitForResponse(response =>
response.url().includes('/api/auth/sign-up/email') && response.status() === 200, response.url().includes('/api/auth/sign-up/email') && response.status() === 200,
{ timeout: 10000 } { timeout: 5000 }
); );
console.log('Admin sign-up API call successful'); console.log('Admin sign-up API call successful');
} catch { } catch {
console.log('Admin sign-up API call failed or timed out'); console.log('Admin sign-up API call failed or timed out');
} }
await page.waitForTimeout(2000); await page.waitForTimeout(500);
const prisma = createPrismaClient(); const prisma = createPrismaClient();
const user = await prisma.user.findUnique({ where: { email: adminEmail } }); const user = await prisma.user.findUnique({ where: { email: adminEmail } });
@@ -159,7 +159,7 @@ async function createTestUsers(config: FullConfig) {
await page.waitForLoadState('domcontentloaded'); await page.waitForLoadState('domcontentloaded');
console.log('Admin page loaded:', page.url()); console.log('Admin page loaded:', page.url());
await page.waitForTimeout(2000); await page.waitForTimeout(500);
await page.reload(); await page.reload();
await page.waitForLoadState('domcontentloaded'); await page.waitForLoadState('domcontentloaded');
console.log('Page reloaded'); console.log('Page reloaded');
+1 -1
View File
@@ -175,7 +175,7 @@ test.describe.serial('Issue #7: Schedule Tab', () => {
await page.click('button:has-text("Generate Schedule")'); await page.click('button:has-text("Generate Schedule")');
// Wait for success message or page reload // Wait for success message or page reload
await page.waitForTimeout(3000); await page.waitForTimeout(500);
// Verify rounds were created in database // Verify rounds were created in database
const rounds = await prisma.tournamentRound.findMany({ const rounds = await prisma.tournamentRound.findMany({
@@ -189,7 +189,7 @@ test.describe.serial('Tournament with 10 Participants and Variable Team Durabili
await page.click('button:has-text("Add")'); await page.click('button:has-text("Add")');
// Wait for the player to be added and UI to update // Wait for the player to be added and UI to update
await page.waitForTimeout(1000); await page.waitForTimeout(200);
} }
// Verify 10 players are added // Verify 10 players are added
+5 -9
View File
@@ -4,16 +4,12 @@ export default defineConfig({
testDir: './e2e', testDir: './e2e',
timeout: 30000, timeout: 30000,
expect: { expect: {
timeout: 5000 timeout: 2000
}, },
// Run tests sequentially to avoid database conflicts // Run tests in parallel for speed - database isolation is per-test via unique data
fullyParallel: false, fullyParallel: true,
// Fail the build on CI if you accidentally left test.only in the source code. // Use multiple workers in CI to speed up test execution
forbidOnly: !!process.env.CI, workers: process.env.CI ? 10 : 1,
// Retry on CI only.
retries: process.env.CI ? 1 : 0,
// Use 1 worker in CI to avoid database conflicts between parallel projects
workers: 1,
// Reporter to use // Reporter to use
reporter: 'html', reporter: 'html',
// Global setup and teardown // Global setup and teardown