upskill-event-manager/wordpress-dev/bin/optimize-tests.sh
bengizmo b3b0901cd6 feat: Add advanced testing resilience and deployment scripts
- Added visual-regression.sh for detecting UI changes
- Created optimize-tests.sh to improve test performance
- Added canary-deploy.sh for safer deployments with automatic rollback
- Enhanced overall testing and deployment reliability

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-05-21 21:05:01 -03:00

347 lines
No EOL
11 KiB
Bash
Executable file

#!/bin/bash
# optimize-tests.sh - Script to optimize test execution and performance
# Usage: ./bin/optimize-tests.sh [analyze|fix|profile] [--verbose]
set -e
# Colors for output
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
RED='\033[0;31m'
NC='\033[0m' # No Color
# Default settings
ACTION=""
VERBOSE=false
CURRENT_DATE=$(date +"%Y-%m-%d")
# Parse arguments
for arg in "$@"; do
case $arg in
analyze|fix|profile)
ACTION="$arg"
shift
;;
--verbose)
VERBOSE=true
shift
;;
esac
done
# Check if action is provided
if [ -z "$ACTION" ]; then
echo -e "${RED}Error: No action specified. Use: analyze, fix, or profile${NC}"
exit 1
fi
echo -e "${GREEN}=== Test Optimization - ${ACTION} ===${NC}"
# Check if we're in the right directory
if [ ! -d "tests/e2e" ]; then
echo -e "${RED}Error: Please run this script from the wordpress-dev directory${NC}"
exit 1
fi
# Create logs directory
mkdir -p logs/optimize
LOG_FILE="logs/optimize/optimize-${ACTION}-${CURRENT_DATE}.log"
# Log function
log() {
echo "[$(date +"%Y-%m-%d %H:%M:%S")] $1" >> "$LOG_FILE"
if [ "$VERBOSE" = true ] || [ -z "$2" ]; then
echo "$1"
else
echo "$2"
fi
}
# Function to analyze test performance
analyze_test_performance() {
log "Analyzing test performance..."
# Check if we have test results
if [ ! -d "test-results" ]; then
log "No test results found. Please run tests first."
return 1
fi
# Create analysis directory
mkdir -p "tests/e2e/analysis"
ANALYSIS_FILE="tests/e2e/analysis/performance-${CURRENT_DATE}.json"
log "Analyzing test duration..."
# Extract test durations from result files
echo "{" > "$ANALYSIS_FILE"
echo " \"date\": \"${CURRENT_DATE}\"," >> "$ANALYSIS_FILE"
echo " \"tests\": [" >> "$ANALYSIS_FILE"
first=true
find test-results -name "*.json" | while read -r file; do
# Extract test name and duration
test_name=$(grep -o '"title":"[^"]*"' "$file" | head -1 | cut -d'"' -f4)
duration=$(grep -o '"duration":[0-9]*' "$file" | cut -d':' -f2)
if [ -n "$test_name" ] && [ -n "$duration" ]; then
# Convert duration to seconds
duration_sec=$(echo "scale=2; $duration/1000" | bc)
# Add to JSON
if [ "$first" = true ]; then
first=false
else
echo "," >> "$ANALYSIS_FILE"
fi
echo " {" >> "$ANALYSIS_FILE"
echo " \"name\": \"${test_name}\"," >> "$ANALYSIS_FILE"
echo " \"duration\": ${duration_sec}" >> "$ANALYSIS_FILE"
echo -n " }" >> "$ANALYSIS_FILE"
# Log slow tests
if (( $(echo "$duration_sec > 5" | bc -l) )); then
log "Slow test detected: ${test_name} (${duration_sec}s)" " - Slow: ${test_name} (${duration_sec}s)"
fi
fi
done
echo "" >> "$ANALYSIS_FILE"
echo " ]" >> "$ANALYSIS_FILE"
echo "}" >> "$ANALYSIS_FILE"
log "Performance analysis saved to ${ANALYSIS_FILE}" "Performance analysis complete."
# Analyze wait operations in test files
log "Analyzing wait operations in test files..."
WAIT_ANALYSIS="tests/e2e/analysis/waits-${CURRENT_DATE}.txt"
echo "Wait Operations Analysis - ${CURRENT_DATE}" > "$WAIT_ANALYSIS"
echo "=================================" >> "$WAIT_ANALYSIS"
echo "" >> "$WAIT_ANALYSIS"
# Find all timeouts in test files
fixed_timeouts=$(grep -r "timeout:" --include="*.ts" tests/e2e | wc -l)
fixed_waits=$(grep -r "waitForTimeout" --include="*.ts" tests/e2e | wc -l)
echo "Fixed Timeouts: ${fixed_timeouts}" >> "$WAIT_ANALYSIS"
echo "Fixed Waits: ${fixed_waits}" >> "$WAIT_ANALYSIS"
echo "" >> "$WAIT_ANALYSIS"
# List files with the most timeouts
echo "Files with most timeouts:" >> "$WAIT_ANALYSIS"
grep -r "timeout:" --include="*.ts" tests/e2e | cut -d: -f1 | sort | uniq -c | sort -nr | head -5 >> "$WAIT_ANALYSIS"
echo "" >> "$WAIT_ANALYSIS"
echo "Files with most waitForTimeout calls:" >> "$WAIT_ANALYSIS"
grep -r "waitForTimeout" --include="*.ts" tests/e2e | cut -d: -f1 | sort | uniq -c | sort -nr | head -5 >> "$WAIT_ANALYSIS"
log "Wait analysis saved to ${WAIT_ANALYSIS}" "Wait analysis complete."
# Analyze selector complexity
log "Analyzing selector complexity..."
SELECTOR_ANALYSIS="tests/e2e/analysis/selectors-${CURRENT_DATE}.txt"
echo "Selector Complexity Analysis - ${CURRENT_DATE}" > "$SELECTOR_ANALYSIS"
echo "===================================" >> "$SELECTOR_ANALYSIS"
echo "" >> "$SELECTOR_ANALYSIS"
# Find complex selectors
echo "Complex selectors:" >> "$SELECTOR_ANALYSIS"
grep -r "selector.*=" --include="*.ts" tests/e2e/pages | grep -v "import" | sort -u >> "$SELECTOR_ANALYSIS"
echo "" >> "$SELECTOR_ANALYSIS"
# Count selector types
echo "Selector types:" >> "$SELECTOR_ANALYSIS"
echo " ID selectors: $(grep -r "\('#" --include="*.ts" tests/e2e | wc -l)" >> "$SELECTOR_ANALYSIS"
echo " Class selectors: $(grep -r "('\\." --include="*.ts" tests/e2e | wc -l)" >> "$SELECTOR_ANALYSIS"
echo " Attribute selectors: $(grep -r "('\[" --include="*.ts" tests/e2e | wc -l)" >> "$SELECTOR_ANALYSIS"
log "Selector analysis saved to ${SELECTOR_ANALYSIS}" "Selector analysis complete."
# Summary
log "Analysis summary:"
log " - Test performance analysis: ${ANALYSIS_FILE}"
log " - Wait operations analysis: ${WAIT_ANALYSIS}"
log " - Selector complexity analysis: ${SELECTOR_ANALYSIS}"
return 0
}
# Function to fix common performance issues
fix_performance_issues() {
log "Fixing common performance issues..."
# Fix waitForTimeout calls
log "Replacing fixed waitForTimeout calls with explicit waits..."
FIXED_COUNT=0
# Find all files with waitForTimeout
files_with_timeouts=$(grep -l "waitForTimeout" --include="*.ts" tests/e2e)
for file in $files_with_timeouts; do
# Create backup
cp "$file" "${file}.bak"
# Replace waitForTimeout with explicit waits
sed -i.tmp 's/await page.waitForTimeout(\([0-9]*\))/await page.waitForLoadState("networkidle")/' "$file"
# Count replacements
replacements=$(diff "$file" "${file}.bak" | grep "waitForTimeout" | wc -l)
FIXED_COUNT=$((FIXED_COUNT + replacements))
# Remove temporary files
rm -f "${file}.tmp"
done
log "Replaced ${FIXED_COUNT} waitForTimeout calls with explicit waits" "Fixed ${FIXED_COUNT} waitForTimeout calls."
# Optimize selectors in page objects
log "Optimizing selectors in page objects..."
# Check LoginPage.ts specifically
if [ -f "tests/e2e/pages/LoginPage.ts" ]; then
# Check if it's already using the optimized selectors
if ! grep -q "input\[name=\"log\"\]" "tests/e2e/pages/LoginPage.ts"; then
log "Updating LoginPage.ts with optimized selectors..."
# Create backup
cp "tests/e2e/pages/LoginPage.ts" "tests/e2e/pages/LoginPage.ts.bak"
# Update selectors
sed -i.tmp 's/private readonly usernameInput = '\''#user_login'\'';/private readonly usernameInput = '\''input[name="log"]'\'';/' "tests/e2e/pages/LoginPage.ts"
sed -i.tmp 's/private readonly passwordInput = '\''#user_pass'\'';/private readonly passwordInput = '\''input[name="pwd"]'\'';/' "tests/e2e/pages/LoginPage.ts"
sed -i.tmp 's/private readonly loginButton = '\''#wp-submit'\'';/private readonly loginButton = '\''input[type="submit"]'\'';/' "tests/e2e/pages/LoginPage.ts"
# Remove temporary files
rm -f "tests/e2e/pages/LoginPage.ts.tmp"
log "LoginPage.ts updated with optimized selectors" "LoginPage.ts optimized."
else
log "LoginPage.ts already using optimized selectors" "LoginPage.ts already optimized."
fi
fi
# Optimize playwright.config.ts
if [ -f "playwright.config.ts" ]; then
log "Optimizing Playwright configuration..."
# Create backup
cp "playwright.config.ts" "playwright.config.ts.bak"
# Check if already optimized
if ! grep -q "workers: 2" "playwright.config.ts"; then
# Add worker limit
sed -i.tmp 's/use: {/use: {\n workers: 2,/' "playwright.config.ts"
log "Updated Playwright configuration with worker limit" "Added worker limit to config."
else
log "Playwright configuration already has worker limit" "Worker limit already set."
fi
# Check for retry configuration
if ! grep -q "retries:" "playwright.config.ts"; then
# Add retry configuration
sed -i.tmp 's/projects: \[/retries: process.env.CI ? 2 : 0,\n projects: \[/' "playwright.config.ts"
log "Added retry configuration to Playwright config" "Added retry configuration."
else
log "Playwright configuration already has retry settings" "Retry settings already configured."
fi
# Remove temporary files
rm -f "playwright.config.ts.tmp"
fi
log "Performance optimizations complete."
return 0
}
# Function to profile test execution
profile_test_execution() {
log "Profiling test execution..."
# Create a profile test file
PROFILE_TEST="tests/e2e/profile-test.spec.ts"
log "Creating profile test..."
cat > "$PROFILE_TEST" << 'EOF'
import { test } from '@playwright/test';
import { LoginPage } from './pages/LoginPage';
import { TEST_USERS } from './data/test-users';
test('Profile test performance', async ({ page }) => {
console.time('Total');
// Login page
const loginPage = new LoginPage(page);
console.time('Navigate to login');
await loginPage.navigate();
console.timeEnd('Navigate to login');
console.time('Login');
await loginPage.login(TEST_USERS.trainer.username, TEST_USERS.trainer.password);
console.timeEnd('Login');
console.time('Load dashboard');
await page.waitForLoadState('networkidle');
console.timeEnd('Load dashboard');
console.time('Screenshot');
await page.screenshot({ path: 'screenshots/profile-test.png' });
console.timeEnd('Screenshot');
console.timeEnd('Total');
});
EOF
log "Running profile test..."
# Create profile output directory
mkdir -p "tests/e2e/profile"
PROFILE_OUTPUT="tests/e2e/profile/profile-${CURRENT_DATE}.txt"
# Run the profile test with trace
npx playwright test "$PROFILE_TEST" --trace on > "$PROFILE_OUTPUT" 2>&1
# Extract timing information
log "Extracting timing information..."
echo "Performance Profile - ${CURRENT_DATE}" > "tests/e2e/profile/summary-${CURRENT_DATE}.txt"
echo "=================================" >> "tests/e2e/profile/summary-${CURRENT_DATE}.txt"
echo "" >> "tests/e2e/profile/summary-${CURRENT_DATE}.txt"
# Extract console.time entries
grep -E "Navigate to login|Login|Load dashboard|Screenshot|Total" "$PROFILE_OUTPUT" |
grep -v "console.time" >> "tests/e2e/profile/summary-${CURRENT_DATE}.txt"
# Clean up
rm "$PROFILE_TEST"
log "Profile results:"
cat "tests/e2e/profile/summary-${CURRENT_DATE}.txt"
log "Profiling complete. Results saved to tests/e2e/profile/summary-${CURRENT_DATE}.txt"
return 0
}
# Execute action
case $ACTION in
"analyze")
analyze_test_performance
;;
"fix")
fix_performance_issues
;;
"profile")
profile_test_execution
;;
*)
log "Invalid action: ${ACTION}"
exit 1
;;
esac
log "Test optimization ${ACTION} completed successfully."
exit 0