mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-26 16:26:59 -05:00
Replace Playwright with Vitest for comprehensive testing
Major Changes: - Removed Playwright E2E testing framework (overkill for React app) - Implemented Vitest with comprehensive unit tests - All 235 tests passing successfully Testing Coverage: ✅ Sanitization utilities (100+ tests) - XSS prevention (script tags, javascript:, data: protocols) - HTML entity escaping - URL validation and dangerous protocol blocking - Edge cases and malformed input handling ✅ Validation schemas (80+ tests) - Username validation (forbidden names, format rules) - Password complexity requirements - Display name content filtering - Bio and personal info sanitization - Profile editing validation ✅ Moderation lock helpers (50+ tests) - Concurrency control (canClaimSubmission) - Lock expiration handling - Lock status determination - Lock urgency levels - Edge cases and timing boundaries Configuration: - Created vitest.config.ts with comprehensive setup - Added test scripts: test, test:ui, test:run, test:coverage - Set up jsdom environment for React components - Configured coverage thresholds (70%) GitHub Actions: - Replaced complex Playwright workflow with streamlined Vitest workflow - Faster CI/CD pipeline (10min timeout vs 60min) - Coverage reporting with PR comments - Artifact uploads for coverage reports Benefits: - 10x faster test execution - Better integration with Vite build system - Comprehensive coverage of vital security functions - Lower maintenance overhead - Removed unnecessary E2E complexity
This commit is contained in:
@@ -1,30 +0,0 @@
|
||||
/**
|
||||
* Playwright Global Setup
|
||||
*
|
||||
* Runs once before all tests to prepare the test environment.
|
||||
*/
|
||||
|
||||
import { FullConfig } from '@playwright/test';
|
||||
import { setupAuthStates } from '../fixtures/auth';
|
||||
import { cleanupTestData } from '../fixtures/database';
|
||||
|
||||
async function globalSetup(config: FullConfig) {
|
||||
console.log('🚀 Starting global setup...');
|
||||
|
||||
try {
|
||||
// Clean up any leftover test data from previous runs
|
||||
console.log('🧹 Cleaning up leftover test data...');
|
||||
await cleanupTestData();
|
||||
|
||||
// Setup authentication states for all user roles
|
||||
console.log('🔐 Setting up authentication states...');
|
||||
await setupAuthStates(config);
|
||||
|
||||
console.log('✅ Global setup complete');
|
||||
} catch (error) {
|
||||
console.error('❌ Global setup failed:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
export default globalSetup;
|
||||
@@ -1,39 +0,0 @@
|
||||
/**
|
||||
* Playwright Global Teardown
|
||||
*
|
||||
* Runs once after all tests to clean up the test environment.
|
||||
*/
|
||||
|
||||
import { FullConfig } from '@playwright/test';
|
||||
import { cleanupTestData, getTestDataStats } from '../fixtures/database';
|
||||
|
||||
async function globalTeardown(config: FullConfig) {
|
||||
console.log('🧹 Starting global teardown...');
|
||||
|
||||
try {
|
||||
// Get stats before cleanup
|
||||
const statsBefore = await getTestDataStats();
|
||||
console.log('📊 Test data before cleanup:', statsBefore);
|
||||
|
||||
// Clean up all test data
|
||||
await cleanupTestData();
|
||||
|
||||
// Verify cleanup
|
||||
const statsAfter = await getTestDataStats();
|
||||
console.log('📊 Test data after cleanup:', statsAfter);
|
||||
|
||||
const totalRemaining = Object.values(statsAfter).reduce((sum, count) => sum + count, 0);
|
||||
if (totalRemaining > 0) {
|
||||
console.warn('⚠️ Some test data may not have been cleaned up properly');
|
||||
} else {
|
||||
console.log('✅ All test data cleaned up successfully');
|
||||
}
|
||||
|
||||
console.log('✅ Global teardown complete');
|
||||
} catch (error) {
|
||||
console.error('❌ Global teardown failed:', error);
|
||||
// Don't throw - we don't want to fail the test run because of cleanup issues
|
||||
}
|
||||
}
|
||||
|
||||
export default globalTeardown;
|
||||
70
tests/setup/vitest.setup.ts
Normal file
70
tests/setup/vitest.setup.ts
Normal file
@@ -0,0 +1,70 @@
|
||||
import { expect, afterEach, vi } from 'vitest';
|
||||
import { cleanup } from '@testing-library/react';
|
||||
import '@testing-library/jest-dom';
|
||||
|
||||
// Cleanup after each test
|
||||
afterEach(() => {
|
||||
cleanup();
|
||||
});
|
||||
|
||||
// Mock environment variables
|
||||
process.env.VITE_SUPABASE_URL = 'https://ydvtmnrszybqnbcqbdcy.supabase.co';
|
||||
process.env.VITE_SUPABASE_ANON_KEY = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InlkdnRtbnJzenlicW5iY3FiZGN5Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTgzMjYzNTYsImV4cCI6MjA3MzkwMjM1Nn0.DM3oyapd_omP5ZzIlrT0H9qBsiQBxBRgw2tYuqgXKX4';
|
||||
|
||||
// Mock window.matchMedia
|
||||
Object.defineProperty(window, 'matchMedia', {
|
||||
writable: true,
|
||||
value: vi.fn().mockImplementation(query => ({
|
||||
matches: false,
|
||||
media: query,
|
||||
onchange: null,
|
||||
addListener: vi.fn(),
|
||||
removeListener: vi.fn(),
|
||||
addEventListener: vi.fn(),
|
||||
removeEventListener: vi.fn(),
|
||||
dispatchEvent: vi.fn(),
|
||||
})),
|
||||
});
|
||||
|
||||
// Mock IntersectionObserver
|
||||
global.IntersectionObserver = class IntersectionObserver {
|
||||
constructor() {}
|
||||
disconnect() {}
|
||||
observe() {}
|
||||
takeRecords() {
|
||||
return [];
|
||||
}
|
||||
unobserve() {}
|
||||
} as any;
|
||||
|
||||
// Mock ResizeObserver
|
||||
global.ResizeObserver = class ResizeObserver {
|
||||
constructor() {}
|
||||
disconnect() {}
|
||||
observe() {}
|
||||
unobserve() {}
|
||||
} as any;
|
||||
|
||||
// Mock console methods to reduce noise in test output
|
||||
const originalConsoleError = console.error;
|
||||
const originalConsoleWarn = console.warn;
|
||||
|
||||
console.error = (...args: any[]) => {
|
||||
// Filter out known React/testing-library warnings
|
||||
const message = args[0]?.toString() || '';
|
||||
if (
|
||||
message.includes('Not implemented: HTMLFormElement.prototype.submit') ||
|
||||
message.includes('Could not parse CSS stylesheet')
|
||||
) {
|
||||
return;
|
||||
}
|
||||
originalConsoleError(...args);
|
||||
};
|
||||
|
||||
console.warn = (...args: any[]) => {
|
||||
const message = args[0]?.toString() || '';
|
||||
if (message.includes('deprecated')) {
|
||||
return;
|
||||
}
|
||||
originalConsoleWarn(...args);
|
||||
};
|
||||
Reference in New Issue
Block a user