- Created WORDPRESS-BEST-PRACTICES.md with complete WP standards guide - Created TESTING-GUIDE.md with E2E testing procedures and display session setup - Updated CLAUDE.md with JavaScript simplification and recent fixes - Enhanced main docs README with new documentation links - Added guidance on MCP Playwright usage vs standard Playwright - Documented proper role checking (roles vs capabilities) - Included display session configuration for headless testing - Added production testing checklists and debug procedures Key additions: - How to use jQuery properly in WordPress (no compatibility layers needed) - Display session setup (DISPLAY=:0) for Playwright testing - Security best practices with proper examples - Common pitfalls and solutions - Test user accounts for staging/production 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
10 KiB
10 KiB
Testing Guide
Overview
This guide provides comprehensive testing procedures for the HVAC Community Events plugin, including E2E testing with Playwright, manual testing procedures, and production verification steps.
Setting Up the Testing Environment
Display Session Configuration
When running tests on a headless server or in CI/CD environments, you need to configure the display session:
# Set display environment variables
export DISPLAY=:0
export XAUTHORITY=/run/user/1000/.mutter-Xwaylandauth.90WDB3
# Verify display is working
echo $DISPLAY
# Should output: :0
# Run tests with display
DISPLAY=:0 node test-trainer-features.js
Why Display Session Matters
- Playwright needs a display to render pages for screenshots
- Some JavaScript interactions require a visible browser
- CSS animations and transitions need a display context
- Debugging is easier with visual feedback
E2E Testing with Playwright
Test Structure
// test-trainer-features.js
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch({
headless: true, // Set to false for debugging
args: ['--no-sandbox']
});
const context = await browser.newContext({
viewport: { width: 1920, height: 1080 }
});
const page = await context.newPage();
// Test implementation
await page.goto('https://upskill-staging.measurequick.com');
// Always close browser
await browser.close();
})();
Using MCP Playwright Tools
MCP Playwright provides better integration with Claude Code:
// Using MCP tools (preferred in Claude Code)
mcp__playwright__browser_navigate({ url: 'https://upskillhvac.com/training-login/' });
mcp__playwright__browser_type({ element: 'Username field', ref: 'e40', text: 'joe@measurequick.com' });
mcp__playwright__browser_click({ element: 'Log In button', ref: 'e50' });
mcp__playwright__browser_snapshot(); // Get page state
mcp__playwright__browser_take_screenshot({ filename: 'login-success.png' });
Key Test Files
# Core test suites
test-all-features.js # Comprehensive test suite
test-trainer-features.js # Trainer-specific features
test-master-dashboard.js # Master trainer dashboard
test-custom-event-edit.js # Event editing functionality
test-registration.js # Registration form validation
# Run specific test
DISPLAY=:0 node test-trainer-features.js
# Run on staging
UPSKILL_STAGING_URL="https://upskill-staging.measurequick.com" node test-all-features.js
Test User Accounts
Staging Environment
Regular Trainer:
- Username: test_trainer
- Password: TestTrainer123!
Master Trainer:
- Username: JoeMedosch@gmail.com
- Password: JoeTrainer2025@
Dual Role (Trainer + Master):
- Username: joe@measurequick.com
- Password: JoeTrainer2025@
Production Environment
Master Trainer:
- Username: joe@measurequick.com
- Password: JoeTrainer2025@
Note: Always test with real accounts in production
Never create test data in production
Manual Testing Procedures
Login Flow Testing
- Navigate to
/training-login/ - Enter credentials
- Verify redirect to appropriate dashboard
- Check navigation menu displays correctly
- Verify role-based features are accessible
Event Management Testing
1. Create Event:
- Navigate to /trainer/event/manage/
- Fill all required fields
- Submit and verify creation
- Check event appears in dashboard
2. Edit Event:
- Navigate to /trainer/event/edit/?event_id=XXX
- Verify form populates with existing data
- Make changes and save
- Verify changes persist
3. Event Permissions:
- Test with different user roles
- Verify trainers can only edit own events
- Check master trainers can view all events
CSS and Layout Testing
1. Responsive Design:
- Test at 320px (mobile)
- Test at 768px (tablet)
- Test at 1920px (desktop)
2. Browser Compatibility:
- Chrome/Edge (Chromium)
- Firefox
- Safari (critical for production)
- Mobile browsers
3. Theme Integration:
- Verify Astra theme compatibility
- Check sidebar removal on plugin pages
- Verify navigation z-index layering
Automated Test Writing Best Practices
Structure Your Tests
describe('Trainer Dashboard', () => {
beforeEach(async () => {
// Login before each test
await loginAsTrainer(page);
});
test('displays user statistics', async () => {
await page.goto('/trainer/dashboard/');
const stats = await page.locator('.hvac-stats-card');
expect(await stats.count()).toBeGreaterThan(0);
});
test('shows events table', async () => {
await page.goto('/trainer/dashboard/');
const table = await page.locator('.hvac-events-table');
expect(await table.isVisible()).toBeTruthy();
});
});
Common Test Patterns
// Wait for navigation
await page.waitForURL('**/dashboard/**');
// Wait for element
await page.waitForSelector('.hvac-dashboard', { timeout: 10000 });
// Check for errors in console
page.on('console', msg => {
if (msg.type() === 'error') {
console.error('Console error:', msg.text());
}
});
// Take screenshot on failure
try {
// Test code
} catch (error) {
await page.screenshot({ path: 'error-screenshot.png' });
throw error;
}
Production Testing Checklist
Pre-deployment Verification
✅ Run pre-deployment validation
bin/pre-deployment-check.sh
✅ Test all features on staging
DISPLAY=:0 node test-all-features.js
✅ Verify no JavaScript errors
Check browser console for errors
✅ Validate CSS rendering
Test in Chrome, Firefox, Safari
✅ Check database operations
Verify CRUD operations work
Post-deployment Verification
✅ Clear all caches
wp cache flush
wp rewrite flush
✅ Test critical paths
- Login flow
- Dashboard access
- Event creation/editing
- Navigation menus
✅ Monitor error logs
tail -f wp-content/debug.log
✅ Verify page load times
Check performance metrics
✅ Test with real user accounts
Use production credentials
Debugging Failed Tests
Common Issues and Solutions
jQuery Errors
// Error: $ is not defined
// Solution: Use jQuery(document).ready()
jQuery(document).ready(function($) {
// $ is now available
});
Permission Errors
// Error: You do not have permission
// Check role properly:
$user = wp_get_current_user();
if (!in_array('hvac_trainer', $user->roles)) {
// No access
}
CSS Not Loading
// Verify page detection
private function is_plugin_page() {
// Check multiple conditions
return $this->check_page_template() ||
$this->check_url_pattern() ||
$this->check_page_id();
}
Debug Output
// Add debug logging
console.log('Current URL:', window.location.href);
console.log('User role:', hvac_ajax.user_role);
console.log('Page ID:', hvac_ajax.page_id);
// Check element state
const element = document.querySelector('.hvac-dashboard');
console.log('Element exists:', !!element);
console.log('Element visible:', element?.offsetParent !== null);
Performance Testing
Load Time Benchmarks
// Measure page load time
const startTime = performance.now();
await page.goto('/trainer/dashboard/');
const loadTime = performance.now() - startTime;
console.log(`Page loaded in ${loadTime}ms`);
// Acceptable thresholds:
// - Homepage: < 2000ms
// - Dashboard: < 3000ms
// - Event forms: < 2500ms
Database Query Monitoring
// Enable query monitoring (development only)
define('SAVEQUERIES', true);
// Log slow queries
add_filter('log_query_custom_data', function($data, $query) {
if ($data['elapsed'] > 0.5) {
error_log('Slow query: ' . $query);
}
return $data;
}, 10, 2);
Security Testing
Authorization Testing
// Test unauthorized access
await page.goto('/trainer/dashboard/');
// Should redirect to login if not authenticated
// Test role-based access
await loginAsRegularUser(page);
await page.goto('/master-trainer/master-dashboard/');
// Should show access denied
Input Validation Testing
// Test XSS prevention
await page.fill('#event_title', '<script>alert("XSS")</script>');
await page.click('#submit');
// Should sanitize input, no alert should appear
// Test SQL injection prevention
await page.fill('#user_email', "admin' OR '1'='1");
// Should reject invalid input
Continuous Integration
GitHub Actions Workflow
name: Test Plugin
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Setup Node
uses: actions/setup-node@v2
with:
node-version: '16'
- name: Install dependencies
run: npm install playwright
- name: Run tests
run: |
export DISPLAY=:99
Xvfb :99 -screen 0 1920x1080x24 &
node test-all-features.js
Test Coverage Goals
Minimum Coverage Requirements
- Authentication: 100% - All login/logout paths
- Authorization: 100% - Role-based access control
- CRUD Operations: 90% - Create, Read, Update, Delete
- UI Components: 80% - Forms, buttons, navigation
- Error Handling: 85% - Error messages, validation
- Edge Cases: 70% - Boundary conditions
Coverage Reporting
# Generate coverage report
npm run test:coverage
# View coverage
open coverage/index.html
Best Practices Summary
- Always test on staging first
- Use real test accounts, not mocked data
- Verify both functionality and UI
- Check browser console for errors
- Test with different user roles
- Take screenshots for debugging
- Clean up test data after tests
- Monitor performance metrics
- Document test failures
- Keep tests maintainable and readable