#!/usr/bin/env node /** * Automated E2E Flow Test for Service Finder Frontend * * This script simulates: * 1. Logging in and getting a token * 2. Setting the Profile Mode (Personal/Fleet) * 3. Fetching the User's Garage * 4. Fetching Gamification stats * * Usage: node automated_flow_test.js */ import axios from 'axios' import { fileURLToPath } from 'url' import { dirname } from 'path' const __filename = fileURLToPath(import.meta.url) const __dirname = dirname(__filename) // Configuration const API_BASE_URL = process.env.VITE_API_BASE_URL || 'https://dev.servicefinder.hu' const TEST_USER_EMAIL = process.env.TEST_USER_EMAIL || 'test@example.com' const TEST_USER_PASSWORD = process.env.TEST_USER_PASSWORD || 'password123' // Create axios instance const api = axios.create({ baseURL: API_BASE_URL, headers: { 'Content-Type': 'application/json', }, }) // Test state let authToken = null let userId = null async function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)) } async function testLogin() { console.log('šŸ” Testing login...') try { // First, check if we need to register a test user // For now, we'll try to login with provided credentials const response = await api.post('/api/v2/auth/login', { email: TEST_USER_EMAIL, password: TEST_USER_PASSWORD, }) if (response.data.access_token) { authToken = response.data.access_token userId = response.data.user_id console.log('āœ… Login successful') console.log(` Token: ${authToken.substring(0, 20)}...`) console.log(` User ID: ${userId}`) // Set auth header for subsequent requests api.defaults.headers.common['Authorization'] = `Bearer ${authToken}` return true } } catch (error) { console.error('āŒ Login failed:', error.response?.data || error.message) // If login fails due to invalid credentials, try to register if (error.response?.status === 401 || error.response?.status === 404) { console.log('āš ļø Attempting to register test user...') try { const registerResponse = await api.post('/api/v2/auth/register', null, { params: { email: TEST_USER_EMAIL, password: TEST_USER_PASSWORD, first_name: 'Test', last_name: 'User', phone: '+36123456789', } }) if (registerResponse.data.access_token) { authToken = registerResponse.data.access_token userId = registerResponse.data.user_id console.log('āœ… Test user registered and logged in') api.defaults.headers.common['Authorization'] = `Bearer ${authToken}` return true } } catch (registerError) { console.error('āŒ Registration failed:', registerError.response?.data || registerError.message) } } } return false } async function testSetProfileMode() { console.log('\nšŸŽÆ Testing profile mode setting...') try { // First, get current user to check existing mode const userResponse = await api.get('/api/v1/users/me') console.log(` Current UI mode: ${userResponse.data.ui_mode || 'not set'}`) // Set mode to 'personal' (private_garage) const modeToSet = 'personal' const response = await api.patch('/api/v1/users/me/preferences', { ui_mode: modeToSet }) console.log(`āœ… Profile mode set to: ${modeToSet}`) // Verify the mode was set const verifyResponse = await api.get('/api/v1/users/me') if (verifyResponse.data.ui_mode === modeToSet) { console.log(`āœ… Mode verified: ${verifyResponse.data.ui_mode}`) return true } else { console.error(`āŒ Mode mismatch: expected ${modeToSet}, got ${verifyResponse.data.ui_mode}`) return false } } catch (error) { console.error('āŒ Failed to set profile mode:', error.response?.data || error.message) return false } } async function testFetchGarage() { console.log('\nšŸš— Testing garage fetch...') try { const response = await api.get('/api/v1/vehicles/my-garage') if (Array.isArray(response.data)) { console.log(`āœ… Garage fetched successfully: ${response.data.length} vehicle(s)`) if (response.data.length > 0) { console.log(' Sample vehicle:', { id: response.data[0].id, make: response.data[0].make, model: response.data[0].model, license_plate: response.data[0].license_plate, }) } return true } else { console.error('āŒ Unexpected garage response format:', response.data) return false } } catch (error) { // Garage might be empty (404) or other error if (error.response?.status === 404) { console.log('āœ… Garage is empty (expected for new user)') return true } console.error('āŒ Failed to fetch garage:', error.response?.data || error.message) return false } } async function testFetchGamification() { console.log('\nšŸ† Testing gamification fetch...') try { // Test achievements endpoint const achievementsResponse = await api.get('/api/v1/gamification/achievements') console.log(`āœ… Achievements fetched: ${achievementsResponse.data.achievements?.length || 0} total`) // Test user stats const statsResponse = await api.get('/api/v1/gamification/me') console.log('āœ… User stats fetched:', { xp: statsResponse.data.xp, level: statsResponse.data.level, rank: statsResponse.data.rank, }) // Test badges const badgesResponse = await api.get('/api/v1/gamification/my-badges') console.log(`āœ… Badges fetched: ${badgesResponse.data?.length || 0} earned`) return true } catch (error) { // Gamification might not be fully implemented if (error.response?.status === 404 || error.response?.status === 501) { console.log('āš ļø Gamification endpoints not fully implemented (expected during development)') return true } console.error('āŒ Failed to fetch gamification:', error.response?.data || error.message) return false } } async function runAllTests() { console.log('šŸš€ Starting Service Finder E2E Flow Test') console.log('=========================================') console.log(`API Base URL: ${API_BASE_URL}`) console.log(`Test User: ${TEST_USER_EMAIL}`) console.log('') const results = { login: false, profileMode: false, garage: false, gamification: false, } // Run tests sequentially results.login = await testLogin() if (!results.login) { console.error('\nāŒ Login failed, aborting further tests') return results } await sleep(1000) // Small delay between tests results.profileMode = await testSetProfileMode() await sleep(500) results.garage = await testFetchGarage() await sleep(500) results.gamification = await testFetchGamification() // Summary console.log('\nšŸ“Š Test Summary') console.log('===============') console.log(`Login: ${results.login ? 'āœ… PASS' : 'āŒ FAIL'}`) console.log(`Profile Mode: ${results.profileMode ? 'āœ… PASS' : 'āŒ FAIL'}`) console.log(`Garage Fetch: ${results.garage ? 'āœ… PASS' : 'āŒ FAIL'}`) console.log(`Gamification: ${results.gamification ? 'āœ… PASS' : 'āŒ FAIL'}`) const allPassed = Object.values(results).every(r => r) console.log(`\n${allPassed ? 'šŸŽ‰ ALL TESTS PASSED' : 'āš ļø SOME TESTS FAILED'}`) return results } // Run tests if script is executed directly if (import.meta.url === `file://${process.argv[1]}`) { runAllTests().then(results => { const allPassed = Object.values(results).every(r => r) process.exit(allPassed ? 0 : 1) }).catch(error => { console.error('šŸ’„ Unhandled error in test runner:', error) process.exit(1) }) } export { runAllTests }