/** * Common step definitions for EuchreCamp E2E tests */ import { Given, When, Then } from '@cucumber/cucumber'; import { expect } from '@playwright/test'; import { world } from '../support/world'; // console.log('🌍 Loading common-steps.ts step definitions'); /** * Navigation steps */ Given('I am on the home page', async function () { console.log('🌍 Navigating to home page'); await world.page.goto(world.baseURL); await world.page.waitForLoadState('networkidle'); }); Given('I am on the registration page', async function () { console.log('🌍 Navigating to registration page'); await world.page.goto(`${world.baseURL}/auth/register`); await world.page.waitForLoadState('networkidle'); }); Given('I am on the login page', async function () { console.log('🌍 Navigating to login page'); await world.page.goto(`${world.baseURL}/auth/login`); await world.page.waitForLoadState('networkidle'); }); Given('I am on the {string} page', async function (pageName: string) { const pageUrls: Record = { 'home': '/', 'home page': '/', 'registration': '/auth/register', 'registration page': '/auth/register', 'login': '/auth/login', 'login page': '/auth/login', 'rankings': '/rankings', 'rankings page': '/rankings', 'admin': '/admin', 'admin page': '/admin', 'admin dashboard': '/admin', 'tournaments': '/admin/tournaments', 'tournaments page': '/admin/tournaments', }; const url = pageUrls[pageName.toLowerCase()] || `/${pageName.toLowerCase().replace(' ', '-')}`; console.log(`🌍 Navigating to ${pageName}: ${url}`); await world.page.goto(`${world.baseURL}${url}`); // Wait for page to load await world.page.waitForLoadState('networkidle'); }); When('I navigate to the {string} page', async function (pageName: string) { // This step is a synonym for "I go to the {string} page" await world.page.goto(`${world.baseURL}/auth/register`); await world.page.waitForLoadState('networkidle'); }); When('I navigate to the registration page', async function () { console.log('🌍 Navigating to registration page'); await world.page.goto(`${world.baseURL}/auth/register`); await world.page.waitForLoadState('networkidle'); }); When('I go to the home page', async function () { console.log('🌍 Navigating to home page'); await world.page.goto(world.baseURL); await world.page.waitForLoadState('networkidle'); }); When('I go to the {string} page', async function (pageName: string) { const pageUrls: Record = { 'home': '/', 'home page': '/', 'registration': '/auth/register', 'registration page': '/auth/register', 'login': '/auth/login', 'login page': '/auth/login', 'rankings': '/rankings', 'rankings page': '/rankings', 'admin': '/admin', 'admin page': '/admin', 'admin dashboard': '/admin', 'tournaments': '/admin/tournaments', 'tournaments page': '/admin/tournaments', }; const url = pageUrls[pageName.toLowerCase()] || `/${pageName.toLowerCase().replace(' ', '-')}`; console.log(`🌍 Going to ${pageName}: ${url}`); await world.page.goto(`${world.baseURL}${url}`); await world.page.waitForLoadState('networkidle'); }); When('I go back', async function () { await world.page.goBack(); await world.page.waitForLoadState('networkidle'); }); When('I refresh the page', async function () { await world.page.reload(); await world.page.waitForLoadState('networkidle'); }); /** * Form interaction steps */ When('I fill in {string} with {string}', async function (fieldName: string, value: string) { // Map field names to selectors const fieldSelectors: Record = { 'name': 'input[name="name"]', 'email': 'input[name="email"]', 'password': 'input[name="password"]', 'confirm password': 'input[name="confirmPassword"]', 'player name': 'input[name="playerName"]', 'tournament name': 'input[name="name"]', }; const selector = fieldSelectors[fieldName.toLowerCase()] || `input[name="${fieldName.toLowerCase()}"]`; console.log(`🌍 Filling ${fieldName} with ${value}`); await world.page.fill(selector, value); }); When('I click the {string} button', async function (buttonText: string) { const selector = `button:has-text("${buttonText}")`; console.log(`🌍 Clicking button: ${buttonText}`); await world.page.click(selector); }); When('I click the {string} link', async function (linkText: string) { const selector = `a:has-text("${linkText}")`; console.log(`🌍 Clicking link: ${linkText}`); await world.page.click(selector); }); When('I click the {string} wordmark', async function (wordmarkText: string) { const selector = `a:has-text("${wordmarkText}")`; console.log(`🌍 Clicking wordmark: ${wordmarkText}`); await world.page.click(selector); await world.page.waitForLoadState('networkidle'); }); When('I click the {string} element', async function (elementText: string) { const selector = `text=${elementText}`; console.log(`🌍 Clicking element: ${elementText}`); await world.page.click(selector); }); /** * Assertion steps */ Then('I should see {string}', async function (text: string) { console.log(`🌍 Checking for text: ${text}`); await expect(world.page.locator(`text=${text}`)).toBeVisible(); }); Then('I should not see {string}', async function (text: string) { console.log(`🌍 Checking text is NOT visible: ${text}`); await expect(world.page.locator(`text=${text}`)).not.toBeVisible(); }); Then('I should be on the {string} page', async function (pageName: string) { const pageUrls: Record = { 'home': '/', 'home page': '/', 'registration': '/auth/register', 'registration page': '/auth/register', 'login': '/auth/login', 'login page': '/auth/login', 'profile': '/players', 'admin': '/admin', 'admin page': '/admin', }; const expectedPath = pageUrls[pageName.toLowerCase()] || `/${pageName.toLowerCase().replace(' ', '-')}`; const currentUrl = world.page.url(); console.log(`🌍 Checking current URL: ${currentUrl}`); console.log(`🌍 Expected path: ${expectedPath}`); expect(currentUrl).toContain(expectedPath); }); Then('I should be redirected to my profile page', async function () { await world.page.waitForLoadState('networkidle'); const currentUrl = world.page.url(); console.log(`🌍 Checking redirect to profile page. Current URL: ${currentUrl}`); expect(currentUrl).toMatch(/\/players\/\d+\/profile/); }); Then('I should be on the registration page', async function () { const currentUrl = world.page.url(); console.log(`🌍 Checking current URL: ${currentUrl}`); expect(currentUrl).toContain('/auth/register'); }); Then('I should be on the login page', async function () { const currentUrl = world.page.url(); console.log(`🌍 Checking current URL: ${currentUrl}`); expect(currentUrl).toContain('/auth/login'); }); Then('I should be on the admin page', async function () { const currentUrl = world.page.url(); console.log(`🌍 Checking current URL: ${currentUrl}`); expect(currentUrl).toContain('/admin'); }); Then('I should be on the home page', async function () { const currentUrl = world.page.url(); console.log(`🌍 Checking current URL: ${currentUrl}`); expect(currentUrl).toContain('/'); }); Then('I should be redirected to {string}', async function (path: string) { await world.page.waitForLoadState('networkidle'); const currentUrl = world.page.url(); console.log(`🌍 Checking redirect to: ${path}`); console.log(`🌍 Current URL: ${currentUrl}`); expect(currentUrl).toContain(path); }); /** * Element visibility steps */ Then('the element {string} should be visible', async function (elementText: string) { const element = world.page.locator(`text=${elementText}`); await expect(element).toBeVisible(); }); Then('the element {string} should not be visible', async function (elementText: string) { const element = world.page.locator(`text=${elementText}`); await expect(element).not.toBeVisible(); }); /** * Wait steps */ When('I wait for {int} seconds', async function (seconds: number) { console.log(`🌍 Waiting ${seconds} seconds`); await world.page.waitForTimeout(seconds * 1000); }); When('I wait for the page to load', async function () { await world.page.waitForLoadState('networkidle'); }); /** * URL verification steps */ Then('the URL should contain {string}', async function (expectedPath: string) { const currentUrl = world.page.url(); console.log(`🌍 Checking URL contains: ${expectedPath}`); expect(currentUrl).toContain(expectedPath); }); Then('I should be redirected to the login page', async function () { await world.page.waitForLoadState('networkidle'); const currentUrl = world.page.url(); console.log(`🌍 Checking redirect to login page. Current URL: ${currentUrl}`); expect(currentUrl).toContain('/auth/login'); }); Then('I should see a {string} error', async function (errorMessage: string) { const content = await world.page.content(); expect(content).toMatch(new RegExp(errorMessage, 'i')); console.log(`🌍 Verified error message: ${errorMessage}`); }); Then('I should see {string} validation error', async function (field: string) { // Look for validation error near the input field const content = await world.page.content(); // Check if the field name is mentioned in an error context expect(content).toMatch(new RegExp(field, 'i')); console.log(`🌍 Verified validation error for: ${field}`); }); Then('I should see {string} error', async function (errorMessage: string) { const content = await world.page.content(); expect(content).toMatch(new RegExp(errorMessage, 'i')); console.log(`🌍 Verified error message: ${errorMessage}`); });