#!/usr/bin/env python3 """ Script de Test Debug - Propriétés d'Étapes VWB Auteur : Dom, Alice, Kiro - 12 janvier 2026 Ce script teste en temps réel le problème des propriétés d'étapes vides en créant un composant de test qui affiche les informations de débogage. """ import os import sys from pathlib import Path def create_debug_component(): """Crée un composant de test pour déboguer les propriétés d'étapes.""" project_root = Path(__file__).parent.parent frontend_path = project_root / "visual_workflow_builder" / "frontend" # Créer le composant de test test_component_path = frontend_path / "src" / "components" / "PropertiesDebugTest.tsx" test_component_content = '''/** * Composant de Test Debug - Propriétés d'Étapes * Auteur : Dom, Alice, Kiro - 12 janvier 2026 * * Ce composant teste et affiche les informations de débogage pour * diagnostiquer le problème des propriétés d'étapes vides. */ import React, { useState, useCallback, useMemo } from 'react'; import { Box, Typography, Button, Card, CardContent, Alert, Accordion, AccordionSummary, AccordionDetails, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Paper, Chip, } from '@mui/material'; import { ExpandMore as ExpandMoreIcon, BugReport as BugIcon, CheckCircle as CheckIcon, Error as ErrorIcon, } from '@mui/icons-material'; // Import des types import { Step, StepType, StepExecutionState } from '../types'; // Import des hooks VWB import { useVWBStepIntegration, useIsVWBStep, useVWBActionId } from '../hooks/useVWBStepIntegration'; // Configuration des paramètres (copie de PropertiesPanel) interface ParameterConfig { name: string; label: string; type: 'text' | 'number' | 'boolean' | 'select' | 'visual'; required?: boolean; description?: string; supportVariables?: boolean; options?: { value: string; label: string }[]; defaultValue?: any; min?: number; max?: number; } const stepParametersConfig: Record = { click: [ { name: 'target', label: 'Élément cible', type: 'visual', required: true, description: 'Sélectionner l\\'élément à cliquer', }, { name: 'clickType', label: 'Type de clic', type: 'select', options: [ { value: 'left', label: 'Clic gauche' }, { value: 'right', label: 'Clic droit' }, { value: 'double', label: 'Double-clic' }, ], defaultValue: 'left', }, ], type: [ { name: 'target', label: 'Champ de saisie', type: 'visual', required: true, description: 'Sélectionner le champ où saisir le texte', }, { name: 'text', label: 'Texte à saisir', type: 'text', required: true, supportVariables: true, }, { name: 'clearFirst', label: 'Vider le champ d\\'abord', type: 'boolean', defaultValue: true, }, ], wait: [ { name: 'duration', label: 'Durée (secondes)', type: 'number', required: true, min: 0.1, max: 60, defaultValue: 1, }, ], condition: [ { name: 'condition', label: 'Condition', type: 'text', required: true, supportVariables: true, description: 'Expression conditionnelle à évaluer', }, ], extract: [ { name: 'target', label: 'Élément source', type: 'visual', required: true, description: 'Sélectionner l\\'élément dont extraire les données', }, { name: 'attribute', label: 'Attribut à extraire', type: 'select', options: [ { value: 'text', label: 'Texte' }, { value: 'value', label: 'Valeur' }, { value: 'href', label: 'Lien (href)' }, { value: 'src', label: 'Source (src)' }, ], defaultValue: 'text', }, ], scroll: [ { name: 'direction', label: 'Direction', type: 'select', options: [ { value: 'up', label: 'Vers le haut' }, { value: 'down', label: 'Vers le bas' }, { value: 'left', label: 'Vers la gauche' }, { value: 'right', label: 'Vers la droite' }, ], defaultValue: 'down', }, { name: 'amount', label: 'Quantité (pixels)', type: 'number', defaultValue: 300, min: 1, }, ], navigate: [ { name: 'url', label: 'URL de destination', type: 'text', required: true, supportVariables: true, }, ], screenshot: [ { name: 'filename', label: 'Nom du fichier', type: 'text', supportVariables: true, description: 'Nom du fichier de capture (optionnel)', }, ], }; /** * Composant de test pour déboguer les propriétés d'étapes */ const PropertiesDebugTest: React.FC = () => { const [selectedStepType, setSelectedStepType] = useState('click'); const [testResults, setTestResults] = useState([]); // Hooks VWB const { methods: vwbMethods } = useVWBStepIntegration(); // Créer une étape de test const createTestStep = useCallback((stepType: StepType): Step => { return { id: `test_step_${Date.now()}`, type: stepType, name: `Test ${stepType}`, position: { x: 100, y: 100 }, data: { label: `Test ${stepType}`, stepType: stepType, parameters: {}, }, executionState: StepExecutionState.IDLE, validationErrors: [], }; }, []); // Tester la résolution des paramètres const testParameterResolution = useCallback((stepType: StepType) => { console.log(`🧪 Test de résolution pour le type: ${stepType}`); const testStep = createTestStep(stepType); // Test 1: Configuration directe const directConfig = stepParametersConfig[stepType]; // Test 2: Fonction getParameterConfig simulée const getParameterConfig = (step: Step): ParameterConfig[] => { if (!step) return []; console.log(`🔍 Recherche config pour type: "${step.type}"`); console.log(`🔍 Clés disponibles:`, Object.keys(stepParametersConfig)); console.log(`🔍 Type exact match:`, stepParametersConfig[step.type] !== undefined); return stepParametersConfig[step.type] || []; }; const resolvedConfig = getParameterConfig(testStep); // Test 3: Hooks VWB const isVWBStep = useIsVWBStep(testStep); const vwbActionId = useVWBActionId(testStep); const result = { stepType, testStep, directConfig: directConfig || null, directConfigLength: directConfig ? directConfig.length : 0, resolvedConfig, resolvedConfigLength: resolvedConfig.length, isVWBStep, vwbActionId, configExists: stepParametersConfig[stepType] !== undefined, timestamp: new Date().toISOString(), }; console.log(`✅ Résultat test ${stepType}:`, result); setTestResults(prev => [...prev, result]); return result; }, [createTestStep]); // Tester tous les types d'étapes const testAllStepTypes = useCallback(() => { console.log('🚀 Test de tous les types d\\'étapes'); setTestResults([]); const allTypes: StepType[] = ['click', 'type', 'wait', 'condition', 'extract', 'scroll', 'navigate', 'screenshot']; allTypes.forEach(stepType => { setTimeout(() => testParameterResolution(stepType), 100); }); }, [testParameterResolution]); // Analyser les résultats const analysisResults = useMemo(() => { if (testResults.length === 0) return null; const totalTests = testResults.length; const successfulResolutions = testResults.filter(r => r.resolvedConfigLength > 0).length; const failedResolutions = testResults.filter(r => r.resolvedConfigLength === 0).length; const vwbSteps = testResults.filter(r => r.isVWBStep).length; return { totalTests, successfulResolutions, failedResolutions, vwbSteps, successRate: (successfulResolutions / totalTests) * 100, }; }, [testResults]); return ( Test Debug - Propriétés d'Étapes Ce composant teste la résolution des propriétés d'étapes pour diagnostiquer pourquoi les paramètres apparaissent vides dans l'interface. {/* Contrôles de test */} Contrôles de Test Cliquez sur "Tester Tous les Types" pour exécuter les tests de résolution des paramètres pour chaque type d'étape. {/* Analyse des résultats */} {analysisResults && ( {analysisResults.successRate === 100 ? ( ) : ( )} Analyse des Résultats {analysisResults.failedResolutions > 0 && ( {analysisResults.failedResolutions} type(s) d'étapes ne résolvent pas leurs paramètres correctement. Cela explique pourquoi les propriétés apparaissent vides dans l'interface. )} )} {/* Configuration disponible */} }> Configuration stepParametersConfig Disponible Type d'Étape Nombre de Paramètres Paramètres {Object.entries(stepParametersConfig).map(([stepType, config]) => ( {config.length} {config.map(param => param.name).join(', ')} ))}
{/* Résultats des tests */} {testResults.length > 0 && ( }> Résultats Détaillés des Tests ({testResults.length}) {testResults.map((result, index) => ( Test: {result.stepType} 0 ? 'SUCCÈS' : 'ÉCHEC'} color={result.resolvedConfigLength > 0 ? 'success' : 'error'} /> Configuration Directe {result.directConfigLength} paramètres Configuration Résolue {result.resolvedConfigLength} paramètres Est Action VWB {result.isVWBStep ? 'Oui' : 'Non'} Config Existe {result.configExists ? 'Oui' : 'Non'} {result.resolvedConfigLength === 0 && result.configExists && ( 🚨 PROBLÈME IDENTIFIÉ: La configuration existe ({result.directConfigLength} paramètres) mais la résolution retourne 0 paramètres. Cela indique un problème dans la logique de résolution ou dans le mapping des types. )} }> Détails Techniques {JSON.stringify(result, null, 2)} ))} )}
); }; export default PropertiesDebugTest; ''' try: # Créer le répertoire s'il n'existe pas test_component_path.parent.mkdir(parents=True, exist_ok=True) # Écrire le composant with open(test_component_path, 'w', encoding='utf-8') as f: f.write(test_component_content) print(f"✅ Composant de test créé : {test_component_path}") # Créer aussi un fichier de test simple create_simple_test_script() return True except Exception as e: print(f"❌ Erreur création composant de test : {e}") return False def create_simple_test_script(): """Crée un script de test simple pour vérifier la logique.""" project_root = Path(__file__).parent.parent test_script_path = project_root / "scripts" / "test_simple_proprietes_12jan2026.js" test_script_content = '''/** * Test Simple - Logique de Propriétés d'Étapes * Auteur : Dom, Alice, Kiro - 12 janvier 2026 * * Ce script teste la logique de base pour identifier le problème. */ // Configuration des paramètres (copie simplifiée) const stepParametersConfig = { click: [ { name: 'target', label: 'Élément cible', type: 'visual', required: true }, { name: 'clickType', label: 'Type de clic', type: 'select', defaultValue: 'left' }, ], type: [ { name: 'target', label: 'Champ de saisie', type: 'visual', required: true }, { name: 'text', label: 'Texte à saisir', type: 'text', required: true }, { name: 'clearFirst', label: 'Vider le champ d\\'abord', type: 'boolean', defaultValue: true }, ], wait: [ { name: 'duration', label: 'Durée (secondes)', type: 'number', required: true, defaultValue: 1 }, ], condition: [ { name: 'condition', label: 'Condition', type: 'text', required: true }, ], extract: [ { name: 'target', label: 'Élément source', type: 'visual', required: true }, { name: 'attribute', label: 'Attribut à extraire', type: 'select', defaultValue: 'text' }, ], scroll: [ { name: 'direction', label: 'Direction', type: 'select', defaultValue: 'down' }, { name: 'amount', label: 'Quantité (pixels)', type: 'number', defaultValue: 300 }, ], navigate: [ { name: 'url', label: 'URL de destination', type: 'text', required: true }, ], screenshot: [ { name: 'filename', label: 'Nom du fichier', type: 'text' }, ], }; // Fonction de test (copie de PropertiesPanel) function getParameterConfig(selectedStep) { console.log('🔍 getParameterConfig appelée avec:', selectedStep); if (!selectedStep) { console.log('❌ selectedStep est null/undefined'); return []; } console.log('🔍 selectedStep.type:', selectedStep.type); console.log('🔍 Type de selectedStep.type:', typeof selectedStep.type); console.log('🔍 Clés disponibles dans stepParametersConfig:', Object.keys(stepParametersConfig)); const config = stepParametersConfig[selectedStep.type]; console.log('🔍 Configuration trouvée:', config); console.log('🔍 Longueur de la configuration:', config ? config.length : 0); const result = config || []; console.log('✅ Résultat final:', result); return result; } // Tests console.log('🚀 Début des tests de logique de propriétés d\\'étapes'); console.log('=' .repeat(60)); const testSteps = [ { id: 'test1', type: 'click', name: 'Test Click' }, { id: 'test2', type: 'type', name: 'Test Type' }, { id: 'test3', type: 'wait', name: 'Test Wait' }, { id: 'test4', type: 'invalid', name: 'Test Invalid' }, { id: 'test5', type: 'click_anchor', name: 'Test VWB Click' }, // Action VWB ]; testSteps.forEach((step, index) => { console.log(`\\n🧪 Test ${index + 1}: ${step.name} (type: "${step.type}")`); const config = getParameterConfig(step); console.log(`📊 Résultat: ${config.length} paramètres trouvés`); if (config.length > 0) { console.log('✅ SUCCÈS - Paramètres disponibles:'); config.forEach(param => { console.log(` - ${param.name}: ${param.label} (${param.type})`); }); } else { console.log('❌ ÉCHEC - Aucun paramètre trouvé'); // Diagnostic if (stepParametersConfig[step.type]) { console.log('🚨 PROBLÈME: Configuration existe mais non retournée!'); } else { console.log('ℹ️ INFO: Aucune configuration pour ce type (normal pour les actions VWB)'); } } }); console.log('\\n' + '=' .repeat(60)); console.log('📊 RÉSUMÉ DES TESTS'); console.log('=' .repeat(60)); // Résumé const results = testSteps.map(step => ({ type: step.type, configExists: !!stepParametersConfig[step.type], paramCount: getParameterConfig(step).length, })); results.forEach(result => { const status = result.paramCount > 0 ? '✅' : '❌'; console.log(`${status} ${result.type}: ${result.paramCount} paramètres (config existe: ${result.configExists})`); }); const successCount = results.filter(r => r.paramCount > 0).length; const totalCount = results.length; console.log(`\\n📈 Taux de succès: ${successCount}/${totalCount} (${((successCount/totalCount)*100).toFixed(1)}%)`); if (successCount < totalCount) { console.log('\\n🔧 RECOMMANDATIONS:'); console.log('1. Vérifier que tous les types d\\'étapes ont une configuration'); console.log('2. Vérifier la logique de détection des actions VWB'); console.log('3. Ajouter des logs dans le composant React pour déboguer en temps réel'); } console.log('\\n✅ Tests terminés'); ''' try: with open(test_script_path, 'w', encoding='utf-8') as f: f.write(test_script_content) print(f"✅ Script de test simple créé : {test_script_path}") return True except Exception as e: print(f"❌ Erreur création script de test : {e}") return False def main(): """Fonction principale.""" print("🧪 Création des outils de test pour déboguer les propriétés d'étapes") success = create_debug_component() if success: print("\n✅ Outils de test créés avec succès!") print("\n📋 PROCHAINES ÉTAPES:") print("1. Intégrer le composant PropertiesDebugTest dans l'application") print("2. Exécuter le script de test simple avec Node.js") print("3. Analyser les résultats pour identifier le problème exact") print("4. Implémenter la correction basée sur les résultats") print("\n🔧 COMMANDES À EXÉCUTER:") print("# Test simple JavaScript:") print("node scripts/test_simple_proprietes_12jan2026.js") print("\n# Intégrer le composant de test dans App.tsx (temporairement)") print("# Puis tester dans le navigateur") return 0 else: print("\n❌ Échec de la création des outils de test") return 1 if __name__ == "__main__": sys.exit(main())