95 lines
2.7 KiB
TypeScript
95 lines
2.7 KiB
TypeScript
import { APIRequestContext } from '@playwright/test';
|
|
import { TestUser } from '../types';
|
|
|
|
/**
|
|
* Authentication utilities for API and browser-based logins
|
|
*/
|
|
export class AuthUtils {
|
|
/**
|
|
* Pre-seeded Fellowship members for testing
|
|
*/
|
|
static readonly FELLOWSHIP_MEMBERS: Record<string, TestUser> = {
|
|
frodo: { username: 'frodo_baggins', password: 'fellowship123', character: 'Frodo Baggins' },
|
|
sam: { username: 'samwise_gamgee', password: 'fellowship123', character: 'Samwise Gamgee' },
|
|
aragorn: { username: 'aragorn', password: 'fellowship123', character: 'Aragorn' },
|
|
legolas: { username: 'legolas', password: 'fellowship123', character: 'Legolas' },
|
|
gimli: { username: 'gimli', password: 'fellowship123', character: 'Gimli' },
|
|
gandalf: { username: 'gandalf', password: 'fellowship123', character: 'Gandalf' },
|
|
};
|
|
|
|
/**
|
|
* Get a random Fellowship member for testing
|
|
*/
|
|
static getRandomMember(): TestUser {
|
|
const members = Object.values(this.FELLOWSHIP_MEMBERS);
|
|
return members[Math.floor(Math.random() * members.length)];
|
|
}
|
|
|
|
/**
|
|
* Get a Fellowship member by username or key
|
|
*/
|
|
static getFellowshipMember(usernameOrKey: string): TestUser {
|
|
// Try to find by key first (e.g., "frodo", "sam")
|
|
if (this.FELLOWSHIP_MEMBERS[usernameOrKey]) {
|
|
return this.FELLOWSHIP_MEMBERS[usernameOrKey];
|
|
}
|
|
|
|
// Try to find by username (e.g., "frodo_baggins")
|
|
const member = Object.values(this.FELLOWSHIP_MEMBERS).find(
|
|
m => m.username === usernameOrKey
|
|
);
|
|
|
|
if (member) {
|
|
return member;
|
|
}
|
|
|
|
// If not found, throw an error
|
|
throw new Error(`Fellowship member not found: ${usernameOrKey}`);
|
|
}
|
|
|
|
/**
|
|
* Login via API and set cookies in page
|
|
*/
|
|
static async loginViaApi(
|
|
apiRequest: APIRequestContext,
|
|
baseUrl: string,
|
|
user: TestUser,
|
|
): Promise<void> {
|
|
const response = await apiRequest.post(`${baseUrl}/api/auth/login`, {
|
|
data: {
|
|
username: user.username,
|
|
password: user.password,
|
|
},
|
|
});
|
|
|
|
if (!response.ok()) {
|
|
throw new Error(`Login failed: ${response.status()} ${await response.text()}`);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Logout via API
|
|
*/
|
|
static async logoutViaApi(apiRequest: APIRequestContext, baseUrl: string): Promise<void> {
|
|
const response = await apiRequest.post(`${baseUrl}/api/auth/logout`);
|
|
if (!response.ok()) {
|
|
console.warn(`Logout returned ${response.status()}, but continuing...`);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Verify session is authenticated
|
|
*/
|
|
static async verifySessionAuthenticated(
|
|
apiRequest: APIRequestContext,
|
|
baseUrl: string,
|
|
): Promise<boolean> {
|
|
try {
|
|
const response = await apiRequest.get(`${baseUrl}/api/auth/me`);
|
|
return response.ok();
|
|
} catch {
|
|
return false;
|
|
}
|
|
}
|
|
}
|