Files
gymflow/tests/fixtures.ts

89 lines
3.6 KiB
TypeScript

import { test as base, expect } from '@playwright/test';
import { request } from '@playwright/test';
import { exec as cp_exec } from 'child_process';
import { promisify } from 'util';
const exec = promisify(cp_exec);
// Define the type for our custom fixtures
type MyFixtures = {
createUniqueUser: () => Promise<{ email: string, password: string, id: string, token: string }>;
createAdminUser: () => Promise<{ email: string, password: string, id: string, token: string }>;
};
// Extend the base test with our custom fixture
export const test = base.extend<MyFixtures>({
createUniqueUser: async ({ }, use) => {
// We use a new API context for setup to avoid polluting request history,
// although setup requests are usually separate anyway.
const apiContext = await request.newContext({
baseURL: 'http://127.0.0.1:3001' // Direct access to backend
});
// Setup: Helper function to create a user
const createUser = async () => {
const uniqueId = Math.random().toString(36).substring(7);
const email = `test.user.${uniqueId}@example.com`;
const password = 'StrongPassword123!';
const response = await apiContext.post('/api/auth/register', {
data: {
email,
password
}
});
const body = await response.json();
// If registration fails because we hit a collision (unlikely) or other error, fail the test
if (!response.ok()) {
console.error(`REGISTRATION FAILED: ${response.status()} ${response.statusText()}`);
console.error(`RESPONSE BODY: ${JSON.stringify(body, null, 2)}`);
throw new Error(`Failed to register user: ${JSON.stringify(body)}`);
}
return { email, password, id: body.user.id, token: body.token };
};
// Use the fixture
await use(createUser);
// Cleanup: In a real "test:full" env with ephemeral db, cleanup might not be needed.
// But if we want to be clean, we can delete the user.
// Requires admin privileges usually, or specific delete-me endpoint.
// Given the requirements "delete own account" exists (5.6), we could theoretically login and delete.
// For now we skip auto-cleanup to keep it simple, assuming test DB is reset periodically.
},
createAdminUser: async ({ createUniqueUser }, use) => {
// Setup: Helper function to create an admin user (create regular -> promote)
const createAdmin = async () => {
const user = await createUniqueUser(); // Create a regular user first
console.log(`Promoting user ${user.email} to ADMIN...`);
try {
const { stdout, stderr } = await exec(`npx ts-node promote_admin.ts ${user.email}`, {
cwd: 'server',
env: { ...process.env, APP_MODE: 'test', DATABASE_URL: 'file:./prisma/test.db', DATABASE_URL_TEST: 'file:./prisma/test.db' }
});
if (stderr) {
console.error(`Promote Admin Stderr: ${stderr}`);
}
console.log(`Promote Admin Stdout: ${stdout}`);
if (!stdout.includes(`User ${user.email} promoted to ADMIN`)) {
throw new Error('Admin promotion failed or unexpected output.');
}
} catch (error) {
console.error(`Error promoting user ${user.email} to ADMIN:`, error);
throw error;
}
return user;
};
await use(createAdmin);
},
});
export { expect };