import fs from 'fs'; import path from 'path'; import { fileURLToPath } from 'url'; import fetch from 'node-fetch'; import dotenv from 'dotenv'; import chalk from 'chalk'; // Load .env file dotenv.config(); const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); // Configuration const GRAPHQL_ENDPOINT = process.env.GRAPHQL_ENDPOINT || 'https://venabo.phx-erp.cloud/backend-api/admin-api'; const AUTH_TOKEN = process.env.AUTH_TOKEN; const VERBOSE = process.argv.includes('--verbose'); function log(message) { console.log(message); } function parseGraphQLFile(filePath) { try { const content = fs.readFileSync(filePath, 'utf-8'); const lines = content.split('\n'); // Extract query name and type const firstLine = lines[0].trim(); const queryType = firstLine.startsWith('query') ? 'query' : firstLine.startsWith('mutation') ? 'mutation' : firstLine.startsWith('subscription') ? 'subscription' : 'query'; return { name: path.basename(filePath, '.gql'), type: queryType, query: content.trim(), }; } catch (error) { throw new Error(`Failed to parse ${filePath}: ${error.message}`); } } async function runGraphQLTest(test) { try { log(`\n${chalk.cyan.bold('Testing:')} ${chalk.cyan(test.name)}`); if (VERBOSE) { log(` ${chalk.gray('Type:')} ${chalk.yellow(test.type)}`); log(` ${chalk.gray('Query:')}`); console.log(test.query.split('\n').map(line => ` ${chalk.gray(line)}`).join('\n')); } const response = await fetch(GRAPHQL_ENDPOINT, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${AUTH_TOKEN}`, }, body: JSON.stringify({ query: test.query, }), }); const text = await response.text(); let result; try { result = JSON.parse(text); } catch (e) { throw new Error(`HTTP ${response.status}: ${response.statusText}. Response: ${text.substring(0, 200)}`); } if (result.errors) { log(` ${chalk.red.bold('Errors found:')}`); result.errors.forEach(error => { log(` ${chalk.red('✗')} ${chalk.red(error.message)}`); if (VERBOSE && error.locations) { error.locations.forEach(loc => { log(` ${chalk.gray(`Line ${loc.line}, Column ${loc.column}`)}`); }); } if (VERBOSE && error.path) { log(` ${chalk.gray(`Path: ${error.path.join('.')}`)}`); } }); return { success: false, test, result }; } if (!response.ok) { throw new Error(`HTTP ${response.status}: ${response.statusText}`); } log(` ${chalk.green.bold('✓ Success')}`); if (VERBOSE && result.data) { log(` ${chalk.gray('Response:')}`); console.log(JSON.stringify(result.data, null, 2)); } return { success: true, test, result }; } catch (error) { log(` ${chalk.red.bold('✗ Failed:')} ${chalk.red(error.message)}`); return { success: false, test, error: error.message }; } } async function main() { log(chalk.bold.blue('Venabo GraphQL Test Runner\n')); log(`${chalk.gray('Endpoint:')} ${chalk.cyan(GRAPHQL_ENDPOINT)}`); // Find all .gql files const files = fs.readdirSync(__dirname) .filter(file => file.endsWith('.gql')) .map(file => path.join(__dirname, file)); if (files.length === 0) { log(chalk.yellow('No .gql files found in the current directory')); process.exit(0); } log(`${chalk.gray('Found')} ${chalk.cyan(files.length)} ${chalk.gray('test file(s)\n')}`); // Parse all test files const tests = files.map(parseGraphQLFile); // Run all tests const results = await Promise.all(tests.map(runGraphQLTest)); // Summary const passed = results.filter(r => r.success).length; const failed = results.filter(r => !r.success).length; log('\n' + chalk.gray('='.repeat(50))); log(chalk.bold('Summary:')); log(` ${chalk.green.bold('Passed:')} ${chalk.green(passed)}`); log(` ${chalk.red.bold('Failed:')} ${chalk.red(failed)}`); log(chalk.gray('='.repeat(50)) + '\n'); process.exit(failed > 0 ? 1 : 0); } main().catch(error => { log(`\n${chalk.red.bold('Fatal error:')} ${chalk.red(error.message)}`); process.exit(1); });