upskill-event-manager/tests/helpers/auth-fixtures.js
Ben 7c9ca65cf2
Some checks are pending
HVAC Plugin CI/CD Pipeline / Security Analysis (push) Waiting to run
HVAC Plugin CI/CD Pipeline / Code Quality & Standards (push) Waiting to run
HVAC Plugin CI/CD Pipeline / Unit Tests (push) Waiting to run
HVAC Plugin CI/CD Pipeline / Integration Tests (push) Waiting to run
HVAC Plugin CI/CD Pipeline / Deploy to Staging (push) Blocked by required conditions
HVAC Plugin CI/CD Pipeline / Deploy to Production (push) Blocked by required conditions
HVAC Plugin CI/CD Pipeline / Notification (push) Blocked by required conditions
Security Monitoring & Compliance / Dependency Vulnerability Scan (push) Waiting to run
Security Monitoring & Compliance / Secrets & Credential Scan (push) Waiting to run
Security Monitoring & Compliance / WordPress Security Analysis (push) Waiting to run
Security Monitoring & Compliance / Static Code Security Analysis (push) Waiting to run
Security Monitoring & Compliance / Security Compliance Validation (push) Waiting to run
Security Monitoring & Compliance / Security Summary Report (push) Blocked by required conditions
Security Monitoring & Compliance / Security Team Notification (push) Blocked by required conditions
feat: add comprehensive test framework and test files
- Add 90+ test files including E2E, unit, and integration tests
- Implement Page Object Model (POM) architecture
- Add Docker testing environment with comprehensive services
- Include modernized test framework with error recovery
- Add specialized test suites for master trainer and trainer workflows
- Update .gitignore to properly track test infrastructure

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-29 23:23:26 -03:00

293 lines
No EOL
8.9 KiB
JavaScript

/**
* Authentication Fixtures for Playwright Tests
*
* Provides reusable authentication fixtures with state management:
* - Automatic authentication setup
* - State persistence across tests
* - Role-based test isolation
* - Performance optimization
* - Error handling
*
* @package HVAC_Community_Events
* @version 3.0.0
* @created 2025-08-20
*/
const { test: base, expect } = require('@playwright/test');
const LoginPage = require('./LoginPage');
const {
getAuthStatePath,
saveAuthState,
clearAuthState,
verifyAuthentication,
getUserConfig
} = require('./auth.setup');
/**
* Extended test with authentication fixtures
*/
const test = base.extend({
/**
* Authenticated trainer page
*/
authenticatedTrainerPage: async ({ browser }, use) => {
const context = await browser.newContext();
const page = await context.newPage();
const loginPage = new LoginPage(page);
try {
await loginPage.loginWithStateManagement('trainer', context);
await use(page);
} finally {
await context.close();
}
},
/**
* Authenticated master trainer page
*/
authenticatedMasterTrainerPage: async ({ browser }, use) => {
const context = await browser.newContext();
const page = await context.newPage();
const loginPage = new LoginPage(page);
try {
await loginPage.loginWithStateManagement('master_trainer', context);
await use(page);
} finally {
await context.close();
}
},
/**
* Authenticated admin page
*/
authenticatedAdminPage: async ({ browser }, use) => {
const context = await browser.newContext();
const page = await context.newPage();
const loginPage = new LoginPage(page);
try {
await loginPage.loginWithStateManagement('admin', context);
await use(page);
} finally {
await context.close();
}
},
/**
* Login page helper
*/
loginPage: async ({ page }, use) => {
const loginPage = new LoginPage(page);
await use(loginPage);
},
/**
* Multi-role context for testing role switching
*/
multiRoleContext: async ({ browser }, use) => {
const contexts = {};
const pages = {};
try {
// Create contexts for each role
for (const userType of ['trainer', 'master_trainer', 'admin']) {
contexts[userType] = await browser.newContext();
pages[userType] = await contexts[userType].newPage();
const loginPage = new LoginPage(pages[userType]);
await loginPage.loginWithStateManagement(userType, contexts[userType]);
}
await use({ contexts, pages });
} finally {
// Clean up all contexts
for (const context of Object.values(contexts)) {
await context.close();
}
}
}
});
/**
* Authentication test helpers
*/
const authHelpers = {
/**
* Login to page as specific user type
* @param {Page} page - Playwright page
* @param {string} userType - User type
* @param {Object} options - Login options
*/
async loginAs(page, userType, options = {}) {
const loginPage = new LoginPage(page);
await loginPage.login(userType, options);
},
/**
* Verify user authentication and role
* @param {Page} page - Playwright page
* @param {string} expectedUserType - Expected user type
*/
async verifyAuth(page, expectedUserType) {
await verifyAuthentication(page, expectedUserType);
},
/**
* Setup authentication for test suite
* @param {string} userType - Default user type for suite
*/
setupAuth(userType = 'trainer') {
return {
beforeEach: async ({ page }) => {
await authHelpers.loginAs(page, userType);
},
afterEach: async ({ page }) => {
// Optional: logout after each test
if (process.env.LOGOUT_AFTER_TEST) {
const loginPage = new LoginPage(page);
await loginPage.logout();
}
}
};
},
/**
* Create authentication test context with state management
* @param {Browser} browser - Playwright browser
* @param {string} userType - User type
* @returns {Object} Context and page with authentication
*/
async createAuthContext(browser, userType) {
// Try to use saved authentication state
const authStatePath = await getAuthStatePath(userType);
let context;
if (authStatePath) {
try {
context = await browser.newContext({ storageState: authStatePath });
const page = await context.newPage();
// Verify saved state is still valid
await verifyAuthentication(page, userType);
console.log(`✅ Using saved auth state for ${userType}`);
return { context, page };
} catch (error) {
console.log(`⚠️ Saved auth state invalid for ${userType}, creating fresh context`);
await context?.close();
}
}
// Create fresh context and login
context = await browser.newContext();
const page = await context.newPage();
const loginPage = new LoginPage(page);
await loginPage.login(userType);
await saveAuthState(userType, context);
return { context, page };
},
/**
* Clear all authentication states (for test cleanup)
*/
async clearAllAuthStates() {
await clearAuthState();
},
/**
* Get user configuration for testing
* @param {string} userType - User type
* @returns {Object} User configuration
*/
getUserConfig(userType) {
return getUserConfig(userType);
}
};
/**
* Authentication test scenarios
*/
const authScenarios = {
/**
* Test authentication for all user types
* @param {Function} testFn - Test function to run for each user type
*/
forAllUserTypes(testFn) {
const userTypes = ['trainer', 'master_trainer', 'admin'];
for (const userType of userTypes) {
test(`${userType} authentication`, async ({ browser }) => {
const { context, page } = await authHelpers.createAuthContext(browser, userType);
try {
await testFn(page, userType);
} finally {
await context.close();
}
});
}
},
/**
* Test role-based access control
* @param {Object} roleTests - Map of userType to test function
*/
forRoleAccess(roleTests) {
for (const [userType, testFn] of Object.entries(roleTests)) {
test(`${userType} role access`, async ({ browser }) => {
const { context, page } = await authHelpers.createAuthContext(browser, userType);
try {
await testFn(page, userType);
} finally {
await context.close();
}
});
}
},
/**
* Test unauthorized access (should be blocked)
* @param {string} authorizedUserType - User type that should have access
* @param {string[]} unauthorizedUserTypes - User types that should NOT have access
* @param {Function} testFn - Test function that should fail for unauthorized users
*/
testUnauthorizedAccess(authorizedUserType, unauthorizedUserTypes, testFn) {
// Test authorized access
test(`${authorizedUserType} authorized access`, async ({ browser }) => {
const { context, page } = await authHelpers.createAuthContext(browser, authorizedUserType);
try {
await testFn(page, authorizedUserType, true); // Should succeed
} finally {
await context.close();
}
});
// Test unauthorized access
for (const userType of unauthorizedUserTypes) {
test(`${userType} unauthorized access blocked`, async ({ browser }) => {
const { context, page } = await authHelpers.createAuthContext(browser, userType);
try {
await expect(async () => {
await testFn(page, userType, false); // Should fail
}).rejects.toThrow();
} finally {
await context.close();
}
});
}
}
};
module.exports = {
test,
expect,
authHelpers,
authScenarios,
LoginPage
};