nextjs-rewrite (#5)

Reviewed-on: #5
Co-authored-by: David Gwilliam <dhgwilliam@gmail.com>
Co-committed-by: David Gwilliam <dhgwilliam@gmail.com>
This commit was merged in pull request #5.
This commit is contained in:
2026-03-30 02:30:13 +00:00
committed by david
parent 1a9b3496e1
commit 123df671f5
160 changed files with 19293 additions and 1180 deletions
@@ -0,0 +1,146 @@
/**
* Acceptance Test: Account Creation, Login, and Deletion (UI-based)
*
* This test demonstrates the full workflow using the UI:
* 1. Create a test account via registration
* 2. Log in using the authentication UI
* 3. Delete the test account
*/
import { test, expect } from '@playwright/test';
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
// Generate unique test account credentials
function getTestCredentials() {
const timestamp = Date.now();
return {
email: `test-${timestamp}@example.com`,
password: 'TestPassword123!',
name: `Test User ${timestamp}`
};
}
test.describe.serial('Account Lifecycle Acceptance Test', () => {
let testEmail: string;
let testPassword: string;
let testName: string;
test.beforeAll(async () => {
const credentials = getTestCredentials();
testEmail = credentials.email;
testPassword = credentials.password;
testName = credentials.name;
});
test.afterAll(async () => {
// Clean up: delete test user if they still exist
try {
const user = await prisma.user.findUnique({
where: { email: testEmail }
});
if (user) {
await prisma.user.delete({ where: { id: user.id } });
console.log(`Cleaned up test user: ${testEmail}`);
}
} catch (error) {
console.error('Cleanup error:', error);
}
});
/**
* Test 1: Create test account via registration
* Uses the unauthenticated project (no storage state)
*/
test('1. Create test account via registration', async ({ page }) => {
// Navigate to registration page
await page.goto('/auth/register');
// Wait for JavaScript to be ready
await page.waitForLoadState('networkidle');
// Wait for the form to be visible and the submit button to be enabled
await page.waitForSelector('form');
await page.waitForSelector('button[type="submit"]:not([disabled])');
// Fill in registration form
await page.fill('input[name="name"]', testName);
await page.fill('input[name="email"]', testEmail);
await page.fill('input[name="password"]', testPassword);
// Submit the form
await page.click('button[type="submit"]');
// Wait for redirect to player profile (regular users are redirected to their profile)
await page.waitForURL(/\/players\/\d+\/profile/, { timeout: 10000 });
// Wait a moment for the user to be saved to database
await page.waitForTimeout(1000);
// Verify user was created in database
const user = await prisma.user.findUnique({
where: { email: testEmail }
});
expect(user).not.toBeNull();
expect(user?.email).toBe(testEmail);
expect(user?.role).toBe('player');
});
/**
* Test 2: Log in with test account
* Uses the unauthenticated project (no storage state)
*/
test('2. Log in with test account', async ({ page }) => {
// Navigate to login page
await page.goto('/auth/login');
// Fill in login form
await page.fill('input[name="email"]', testEmail);
await page.fill('input[name="password"]', testPassword);
// Submit the form
await page.click('button[type="submit"]');
// Wait for redirect to admin or player profile
await page.waitForURL(/\/(admin|players)/, { timeout: 10000 });
// Reload to ensure session is loaded from cookies
await page.reload();
await page.waitForLoadState('networkidle');
// Wait for logout button to appear
await page.waitForSelector('text=Sign out', { timeout: 10000 });
// Check for user's email or name in the navigation
const userEmail = await page.locator(`text=${testEmail}`).count();
const userName = await page.locator(`text=${testName}`).count();
const logoutButton = await page.locator('text=Sign out').count();
// At least one of these should be present if logged in
expect(userEmail + userName + logoutButton).toBeGreaterThan(0);
});
/**
* Test 3: Delete test account
* Uses the authenticated project (admin)
*/
test('3. Delete test account', async ({ page }) => {
// For now, we'll delete via direct database access
// In a real scenario, this would be done via an admin API endpoint
const user = await prisma.user.findUnique({
where: { email: testEmail }
});
if (user) {
await prisma.user.delete({ where: { id: user.id } });
console.log(`Test user deleted: ${testEmail}`);
}
// Verify user was deleted
const deletedUser = await prisma.user.findUnique({
where: { email: testEmail }
});
expect(deletedUser).toBeNull();
});
});