2025-09-27 01:26:58 +02:00
|
|
|
|
const { By, until } = require('selenium-webdriver');
|
|
|
|
|
|
|
|
|
|
|
|
describe('Full Authentication Flow', () => {
|
|
|
|
|
|
let driver;
|
|
|
|
|
|
const timestamp = Date.now();
|
|
|
|
|
|
const testUser = {
|
|
|
|
|
|
name: `Test User ${timestamp}`,
|
|
|
|
|
|
email: `test.user.${timestamp}@example.com`,
|
|
|
|
|
|
password: 'SecurePass123!'
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
beforeAll(async () => {
|
|
|
|
|
|
console.log('🚀 Starting full authentication flow test...');
|
|
|
|
|
|
driver = await global.createDriver();
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
afterAll(async () => {
|
|
|
|
|
|
console.log('🏁 Test complete - cleaning up...');
|
|
|
|
|
|
await global.quitDriver(driver);
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
test('should complete full authentication flow: register → logout → login → dashboard', async () => {
|
|
|
|
|
|
console.log(`\n📧 Test user email: ${testUser.email}\n`);
|
|
|
|
|
|
|
|
|
|
|
|
// STEP 1: Navigate to application
|
|
|
|
|
|
console.log('1️⃣ Navigating to application...');
|
|
|
|
|
|
await driver.get(global.testConfig.baseUrl);
|
|
|
|
|
|
await driver.sleep(2000);
|
|
|
|
|
|
|
|
|
|
|
|
// Verify we're on the auth page
|
|
|
|
|
|
const authContainer = await driver.wait(
|
|
|
|
|
|
until.elementLocated(By.className('auth-container')),
|
|
|
|
|
|
10000,
|
|
|
|
|
|
'Auth container not found - might already be logged in'
|
|
|
|
|
|
);
|
|
|
|
|
|
console.log(' ✓ Auth page loaded');
|
|
|
|
|
|
|
|
|
|
|
|
// STEP 2: Switch to registration form
|
|
|
|
|
|
console.log('\n2️⃣ Switching to registration form...');
|
|
|
|
|
|
const registerTab = await driver.findElement(By.css('.auth-toggle button:last-child'));
|
|
|
|
|
|
await registerTab.click();
|
|
|
|
|
|
await driver.sleep(1000);
|
|
|
|
|
|
|
|
|
|
|
|
// Verify registration form is visible
|
|
|
|
|
|
const regForm = await driver.wait(
|
|
|
|
|
|
until.elementLocated(By.className('registration-form')),
|
|
|
|
|
|
5000
|
|
|
|
|
|
);
|
|
|
|
|
|
console.log(' ✓ Registration form displayed');
|
|
|
|
|
|
|
|
|
|
|
|
// STEP 3: Fill and submit registration form
|
|
|
|
|
|
console.log('\n3️⃣ Filling registration form...');
|
|
|
|
|
|
|
|
|
|
|
|
const nameField = await driver.findElement(By.id('name'));
|
|
|
|
|
|
await nameField.clear();
|
|
|
|
|
|
await nameField.sendKeys(testUser.name);
|
|
|
|
|
|
console.log(` ✓ Name: ${testUser.name}`);
|
|
|
|
|
|
|
|
|
|
|
|
const emailField = await driver.findElement(By.id('email'));
|
|
|
|
|
|
await emailField.clear();
|
|
|
|
|
|
await emailField.sendKeys(testUser.email);
|
|
|
|
|
|
console.log(` ✓ Email: ${testUser.email}`);
|
|
|
|
|
|
|
|
|
|
|
|
const passwordField = await driver.findElement(By.id('password'));
|
|
|
|
|
|
await passwordField.clear();
|
|
|
|
|
|
await passwordField.sendKeys(testUser.password);
|
|
|
|
|
|
console.log(' ✓ Password: ***');
|
|
|
|
|
|
|
|
|
|
|
|
const confirmPasswordField = await driver.findElement(By.id('password_confirmation'));
|
|
|
|
|
|
await confirmPasswordField.clear();
|
|
|
|
|
|
await confirmPasswordField.sendKeys(testUser.password);
|
|
|
|
|
|
console.log(' ✓ Password confirmation: ***');
|
|
|
|
|
|
|
|
|
|
|
|
// Submit registration
|
|
|
|
|
|
console.log('\n4️⃣ Submitting registration...');
|
|
|
|
|
|
const registerButton = await driver.findElement(By.css('.registration-form button[type="submit"]'));
|
|
|
|
|
|
await registerButton.click();
|
|
|
|
|
|
|
|
|
|
|
|
// Wait for registration to complete
|
|
|
|
|
|
await driver.sleep(3000);
|
|
|
|
|
|
|
|
|
|
|
|
// Check for success message or dashboard
|
|
|
|
|
|
let registrationSuccessful = false;
|
|
|
|
|
|
|
|
|
|
|
|
// First check for success message
|
|
|
|
|
|
try {
|
|
|
|
|
|
const successMessage = await driver.findElement(By.className('alert-success'));
|
|
|
|
|
|
const successText = await successMessage.getText();
|
|
|
|
|
|
console.log(` ✓ ${successText}`);
|
|
|
|
|
|
registrationSuccessful = true;
|
|
|
|
|
|
} catch (e) {
|
|
|
|
|
|
console.log(' ℹ️ No success message displayed');
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Check if we're automatically logged in (dashboard visible)
|
|
|
|
|
|
try {
|
|
|
|
|
|
const dashboard = await driver.findElement(By.className('dashboard'));
|
|
|
|
|
|
const isDashboardVisible = await dashboard.isDisplayed();
|
|
|
|
|
|
if (isDashboardVisible) {
|
|
|
|
|
|
console.log(' ✓ Automatically logged in after registration');
|
|
|
|
|
|
registrationSuccessful = true;
|
|
|
|
|
|
|
|
|
|
|
|
// If auto-logged in, we should log out first to test login
|
|
|
|
|
|
console.log('\n5️⃣ Logging out to test login flow...');
|
|
|
|
|
|
|
2025-09-30 08:29:17 +02:00
|
|
|
|
// Look for logout button and click it (now in dropdown)
|
2025-09-27 01:26:58 +02:00
|
|
|
|
try {
|
2025-09-30 08:29:17 +02:00
|
|
|
|
// First click the user dropdown trigger
|
|
|
|
|
|
const userMenuTrigger = await driver.findElement(By.className('user-menu-trigger'));
|
|
|
|
|
|
await userMenuTrigger.click();
|
|
|
|
|
|
await driver.sleep(500);
|
|
|
|
|
|
|
|
|
|
|
|
// Then click the logout button in the dropdown
|
2025-09-27 01:26:58 +02:00
|
|
|
|
const logoutButton = await driver.findElement(By.xpath("//button[contains(text(), 'Logout')]"));
|
|
|
|
|
|
await logoutButton.click();
|
|
|
|
|
|
await driver.sleep(2000);
|
|
|
|
|
|
console.log(' ✓ Logged out successfully');
|
|
|
|
|
|
} catch (e) {
|
2025-09-30 08:29:17 +02:00
|
|
|
|
console.log(' ⚠️ Could not find logout button:', e.message);
|
2025-09-27 01:26:58 +02:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (e) {
|
|
|
|
|
|
console.log(' ℹ️ Not automatically logged in');
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Check for registration errors
|
|
|
|
|
|
if (!registrationSuccessful) {
|
|
|
|
|
|
try {
|
|
|
|
|
|
const errorMessage = await driver.findElement(By.className('alert-error'));
|
|
|
|
|
|
const errorText = await errorMessage.getText();
|
|
|
|
|
|
console.error(` ✗ Registration error: ${errorText}`);
|
|
|
|
|
|
|
|
|
|
|
|
// Check for field-specific errors
|
|
|
|
|
|
const fieldErrors = await driver.findElements(By.className('error-message'));
|
|
|
|
|
|
for (let error of fieldErrors) {
|
|
|
|
|
|
const text = await error.getText();
|
|
|
|
|
|
if (text) console.error(` - ${text}`);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
throw new Error('Registration failed');
|
|
|
|
|
|
} catch (e) {
|
|
|
|
|
|
if (!e.message.includes('Registration failed')) {
|
|
|
|
|
|
console.log(' ℹ️ No error messages found');
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// STEP 6: Test login with the registered credentials
|
|
|
|
|
|
console.log('\n6️⃣ Testing login with registered credentials...');
|
|
|
|
|
|
|
|
|
|
|
|
// Make sure we're back at the auth page
|
|
|
|
|
|
const isAuthPageVisible = await driver.findElements(By.className('auth-container'));
|
|
|
|
|
|
if (isAuthPageVisible.length === 0) {
|
|
|
|
|
|
// Navigate back to home if we're not on auth page
|
|
|
|
|
|
await driver.get(global.testConfig.baseUrl);
|
|
|
|
|
|
await driver.sleep(2000);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Switch to login form
|
|
|
|
|
|
const loginTab = await driver.findElement(By.css('.auth-toggle button:first-child'));
|
|
|
|
|
|
await loginTab.click();
|
|
|
|
|
|
await driver.sleep(1000);
|
|
|
|
|
|
console.log(' ✓ Switched to login form');
|
|
|
|
|
|
|
|
|
|
|
|
// Fill login form
|
|
|
|
|
|
console.log('\n7️⃣ Filling login form...');
|
|
|
|
|
|
const loginEmailField = await driver.findElement(By.css('.login-form #email'));
|
|
|
|
|
|
await loginEmailField.clear();
|
|
|
|
|
|
await loginEmailField.sendKeys(testUser.email);
|
|
|
|
|
|
console.log(` ✓ Email: ${testUser.email}`);
|
|
|
|
|
|
|
|
|
|
|
|
const loginPasswordField = await driver.findElement(By.css('.login-form #password'));
|
|
|
|
|
|
await loginPasswordField.clear();
|
|
|
|
|
|
await loginPasswordField.sendKeys(testUser.password);
|
|
|
|
|
|
console.log(' ✓ Password: ***');
|
|
|
|
|
|
|
|
|
|
|
|
// Submit login
|
|
|
|
|
|
console.log('\n8️⃣ Submitting login...');
|
|
|
|
|
|
const loginButton = await driver.findElement(By.css('.login-form button[type="submit"]'));
|
|
|
|
|
|
await loginButton.click();
|
|
|
|
|
|
|
|
|
|
|
|
// Wait for login to complete
|
|
|
|
|
|
await driver.sleep(3000);
|
|
|
|
|
|
|
|
|
|
|
|
// STEP 9: Verify dashboard access
|
|
|
|
|
|
console.log('\n9️⃣ Verifying dashboard access...');
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
const dashboard = await driver.wait(
|
|
|
|
|
|
until.elementLocated(By.className('dashboard')),
|
|
|
|
|
|
10000
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
const isDashboardVisible = await dashboard.isDisplayed();
|
|
|
|
|
|
expect(isDashboardVisible).toBe(true);
|
|
|
|
|
|
console.log(' ✓ Dashboard is visible');
|
|
|
|
|
|
|
|
|
|
|
|
// Look for welcome message or user info
|
|
|
|
|
|
try {
|
|
|
|
|
|
const dashboardHeading = await driver.findElement(By.css('.dashboard h2'));
|
|
|
|
|
|
const headingText = await dashboardHeading.getText();
|
|
|
|
|
|
console.log(` ✓ Dashboard heading: "${headingText}"`);
|
|
|
|
|
|
} catch (e) {
|
|
|
|
|
|
console.log(' ℹ️ No dashboard heading found');
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Verify user info if available
|
|
|
|
|
|
try {
|
|
|
|
|
|
const userInfo = await driver.findElement(By.className('user-info'));
|
|
|
|
|
|
const userText = await userInfo.getText();
|
|
|
|
|
|
console.log(` ✓ User info displayed: "${userText}"`);
|
|
|
|
|
|
} catch (e) {
|
|
|
|
|
|
console.log(' ℹ️ No user info element found');
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
console.log('\n✅ Full authentication flow completed successfully!');
|
|
|
|
|
|
console.log(` User "${testUser.name}" can register, logout, login, and access the dashboard.`);
|
|
|
|
|
|
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
// Login failed - check for error messages
|
|
|
|
|
|
console.error('\n❌ Login failed or dashboard not accessible');
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
const loginError = await driver.findElement(By.css('.login-form .alert-error'));
|
|
|
|
|
|
const errorText = await loginError.getText();
|
|
|
|
|
|
console.error(` Error message: ${errorText}`);
|
|
|
|
|
|
} catch (e) {
|
|
|
|
|
|
console.error(' No specific error message found');
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Take a screenshot for debugging
|
|
|
|
|
|
const screenshot = await driver.takeScreenshot();
|
|
|
|
|
|
const fs = require('fs');
|
|
|
|
|
|
const path = require('path');
|
|
|
|
|
|
const screenshotPath = path.join(__dirname, `../screenshots/auth-flow-failure-${timestamp}.png`);
|
|
|
|
|
|
|
|
|
|
|
|
// Create screenshots directory if it doesn't exist
|
|
|
|
|
|
const screenshotsDir = path.join(__dirname, '../screenshots');
|
|
|
|
|
|
if (!fs.existsSync(screenshotsDir)) {
|
|
|
|
|
|
fs.mkdirSync(screenshotsDir);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fs.writeFileSync(screenshotPath, screenshot, 'base64');
|
|
|
|
|
|
console.log(` 📸 Screenshot saved to: ${screenshotPath}`);
|
|
|
|
|
|
|
|
|
|
|
|
throw new Error('Dashboard not accessible after login');
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}, 120000); // 2-minute timeout for the full flow
|
|
|
|
|
|
});
|