lotr-sut/tests/e2e/steps/common.steps.ts
Fellowship Scholar f6a5823439 init commit
2026-03-29 20:07:56 +00:00

163 lines
5.7 KiB
TypeScript

import { Given, When, Then, expect } from '../fixtures/bdd-fixtures';
import { AuthUtils } from '../utils/authUtils';
// ===== Background / Setup Steps =====
Given('the Fellowship SUT is running', async ({ page }) => {
try {
const baseUrl = global.fixtures.baseUrl;
const response = await page.request.get(`${baseUrl}/health`);
if (!response.ok()) {
throw new Error(`SUT not running: ${response.status()}`);
}
} catch (e) {
console.warn('SUT health check failed, proceeding with test');
}
});
Given('I am logged in as {string}', async ({ page }, username: string) => {
await global.fixtures.loginPage!.goto();
const user = AuthUtils.getFellowshipMember(username);
await global.fixtures.loginPage!.loginWithUser(user);
await global.fixtures.loginPage!.waitForDashboard();
expect(page.url()).toContain('/dashboard');
});
Given('I navigate to the {string}', async ({ page }, pageName: string) => {
const pageMapping: Record<string, any> = {
'login page': global.fixtures.loginPage,
'dashboard': global.fixtures.dashboardPage,
'quests page': global.fixtures.questsPage,
'map': global.fixtures.mapPage,
};
const targetPage = pageMapping[pageName.toLowerCase()];
if (!targetPage) throw new Error(`Unknown page: ${pageName}`);
await targetPage.goto();
});
Given('I start with {int} gold', async ({ page }, goldAmount: number) => {
global.fixtures.testContext!.goldAmount = goldAmount;
});
// ===== Authentication Steps =====
When('I log in with username {string} and password {string}', async ({ page }, username: string, password: string) => {
try {
const user = AuthUtils.getFellowshipMember(username);
await global.fixtures.loginPage!.loginWithUser(user);
} catch {
await global.fixtures.loginPage!.login(username, password);
}
// Wait for URL to change to dashboard (success) or error to appear (failure)
await Promise.race([
page.waitForURL('**/dashboard', { timeout: 12000 }),
page.waitForSelector('h4', { timeout: 12000 }),
]).catch(() => {
// Let next step handle evaluation
});
});
When('I navigate to the signup page', async () => {
await global.fixtures.loginPage!.goToSignup();
});
When('I sign up with username {string} and password {string}', async ({ page }, username: string, password: string) => {
const uniqueUsername = `${username}_${Date.now()}`;
await global.fixtures.loginPage!.signup(uniqueUsername, password);
await Promise.race([
page.waitForURL('**/dashboard', { timeout: 15000 }),
page.waitForSelector('h4', { timeout: 15000 }),
]).catch(() => {});
});
When('I am on the dashboard', async () => {
const isLoaded = await global.fixtures.dashboardPage!.isLoaded();
expect(isLoaded).toBeTruthy();
});
When('I refresh the page', async ({ page }) => {
await page.reload();
});
When('I click the logout button', async () => {
await global.fixtures.dashboardPage!.logout();
});
When('I try to create a quest without being logged in', async ({ context, page }) => {
const baseUrl = global.fixtures.baseUrl;
const response = await context.request.post(`${baseUrl}/api/quests`, {
data: { title: 'Test' },
});
(global.fixtures.testContext as any).lastErrorStatus = response.status();
});
When('I verify CORS preflight for the login endpoint', async ({ context, page }) => {
const baseUrl = global.fixtures.baseUrl;
(global.fixtures.testContext as any).corsAllowed = await global.fixtures.fixtureUtils.verifyCORSPreflight(
context.request,
baseUrl,
'http://localhost:3000'
);
});
// ===== Assertion Steps =====
Then('I should be redirected to the dashboard', async ({ page }) => {
await page.waitForURL('**/dashboard', { timeout: 15000 });
expect(page.url()).toContain('/dashboard');
});
Then('the dashboard should display a personalized greeting for {string}', async ({ page }, characterName: string) => {
await global.fixtures.dashboardPage!.expectGreetingForCharacter(characterName);
});
Then('I should see an error message containing {string}', async ({ page }, expectedText: string) => {
const isError = await global.fixtures.loginPage!.isErrorVisible();
expect(isError).toBeTruthy();
const errorText = await global.fixtures.loginPage!.getErrorText();
expect(errorText.toLowerCase()).toContain(expectedText.toLowerCase());
});
Then('I should be logged in as {string}', async ({ page }, _username: string) => {
await page.waitForURL('**/dashboard', { timeout: 15000 }).catch(() => {});
expect(page.url()).toContain('/dashboard');
});
Then('I should land on the dashboard', async ({ page }) => {
await page.waitForURL('**/dashboard', { timeout: 15000 }).catch(() => {});
expect(page.url()).toContain('/dashboard');
});
Then('I should still be logged in', async ({ page }) => {
await page.waitForURL('**/dashboard', { timeout: 10000 }).catch(() => {});
expect(page.url()).toContain('/dashboard');
});
Then('the dashboard should be loaded', async () => {
const isLoaded = await global.fixtures.dashboardPage!.isLoaded();
expect(isLoaded).toBeTruthy();
});
Then('I should be redirected to the login page', async ({ page }) => {
await page.waitForURL('**/login', { timeout: 15000 });
expect(page.url()).toContain('/login');
});
Then('the session should be cleared', async ({ page }) => {
await page.waitForURL('**/login', { timeout: 10000 }).catch(() => {});
expect(page.url()).toContain('/login');
});
Then('I should receive an unauthorized error', async () => {
expect((global.fixtures.testContext as any).lastErrorStatus).toBe(401);
});
Then('the response should allow POST requests', async () => {
expect((global.fixtures.testContext as any).corsAllowed).toBeTruthy();
});
Then('the response should include proper CORS headers', async () => {
expect((global.fixtures.testContext as any).corsAllowed).toBeTruthy();
});