File: //srv/rmgun_admin/admin-next/tests/utils/test-helpers.ts
import { Page } from '@playwright/test'
/**
* Helper functions for E2E tests
*/
export class TestHelpers {
/**
* Login to the application
*/
static async login(page: Page, email: string, password: string) {
await page.goto('/login')
await page.fill('input[type="email"]', email)
await page.fill('input[type="password"]', password)
await page.click('button[type="submit"]')
await page.waitForURL('**/dashboard', { timeout: 10000 })
}
/**
* Generate unique test IDs
*/
static generateTestId(prefix: string): string {
return `${prefix}_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`
}
/**
* Wait for API response
*/
static async waitForApiResponse(page: Page, endpoint: string, timeout = 10000) {
return page.waitForResponse(
response => response.url().includes(endpoint) && response.status() === 200,
{ timeout }
)
}
/**
* Clean up test data by prefix
*/
static async cleanupTestData(prefixes: string[], collections: string[]) {
// This would connect to Firebase and clean up test data
// Implementation depends on Firebase Admin SDK setup
console.log(`Cleaning up test data with prefixes: ${prefixes.join(', ')}`)
}
/**
* Take screenshot with descriptive name
*/
static async takeScreenshot(page: Page, name: string) {
const timestamp = new Date().toISOString().replace(/[:.]/g, '-')
await page.screenshot({
path: `test-results/screenshots/${name}-${timestamp}.png`,
fullPage: true,
})
}
/**
* Mock API responses
*/
static async mockApiResponse(page: Page, endpoint: string, response: any) {
await page.route(`**/${endpoint}`, route => {
route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify(response),
})
})
}
/**
* Wait for element and get text
*/
static async getElementText(page: Page, selector: string): Promise<string> {
const element = await page.waitForSelector(selector)
const text = element?.textContent() ?? ''
return text
}
/**
* Check if element exists without throwing
*/
static async elementExists(page: Page, selector: string): Promise<boolean> {
try {
await page.waitForSelector(selector, { timeout: 3000 })
return true
} catch {
return false
}
}
/**
* Retry action with exponential backoff
*/
static async retryAction<T>(
action: () => Promise<T>,
maxRetries = 3,
delay = 1000
): Promise<T> {
let lastError: Error
for (let i = 0; i < maxRetries; i++) {
try {
return await action()
} catch (error) {
lastError = error as Error
if (i < maxRetries - 1) {
await new Promise(resolve => setTimeout(resolve, delay * Math.pow(2, i)))
}
}
}
throw lastError!
}
}