163 lines
5.7 KiB
TypeScript
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();
|
|
});
|