v1.0 - Version stable: multi-PC, détection UI-DETR-1, 3 modes exécution
- Frontend v4 accessible sur réseau local (192.168.1.40) - Ports ouverts: 3002 (frontend), 5001 (backend), 5004 (dashboard) - Ollama GPU fonctionnel - Self-healing interactif - Dashboard confiance Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
726
scripts/test_proprietes_etapes_debug_12jan2026.py
Normal file
726
scripts/test_proprietes_etapes_debug_12jan2026.py
Normal file
@@ -0,0 +1,726 @@
|
||||
#!/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<StepType, ParameterConfig[]> = {
|
||||
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<StepType>('click');
|
||||
const [testResults, setTestResults] = useState<any[]>([]);
|
||||
|
||||
// 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 (
|
||||
<Box sx={{ p: 3, maxWidth: 1200, margin: '0 auto' }}>
|
||||
<Typography variant="h4" gutterBottom sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
|
||||
<BugIcon color="primary" />
|
||||
Test Debug - Propriétés d'Étapes
|
||||
</Typography>
|
||||
|
||||
<Typography variant="body1" color="text.secondary" sx={{ mb: 3 }}>
|
||||
Ce composant teste la résolution des propriétés d'étapes pour diagnostiquer
|
||||
pourquoi les paramètres apparaissent vides dans l'interface.
|
||||
</Typography>
|
||||
|
||||
{/* Contrôles de test */}
|
||||
<Card sx={{ mb: 3 }}>
|
||||
<CardContent>
|
||||
<Typography variant="h6" gutterBottom>
|
||||
Contrôles de Test
|
||||
</Typography>
|
||||
|
||||
<Box sx={{ display: 'flex', gap: 2, mb: 2 }}>
|
||||
<Button
|
||||
variant="contained"
|
||||
onClick={testAllStepTypes}
|
||||
startIcon={<BugIcon />}
|
||||
>
|
||||
Tester Tous les Types
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
variant="outlined"
|
||||
onClick={() => setTestResults([])}
|
||||
>
|
||||
Vider les Résultats
|
||||
</Button>
|
||||
</Box>
|
||||
|
||||
<Typography variant="body2" color="text.secondary">
|
||||
Cliquez sur "Tester Tous les Types" pour exécuter les tests de résolution
|
||||
des paramètres pour chaque type d'étape.
|
||||
</Typography>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{/* Analyse des résultats */}
|
||||
{analysisResults && (
|
||||
<Card sx={{ mb: 3 }}>
|
||||
<CardContent>
|
||||
<Typography variant="h6" gutterBottom sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
|
||||
{analysisResults.successRate === 100 ? (
|
||||
<CheckIcon color="success" />
|
||||
) : (
|
||||
<ErrorIcon color="error" />
|
||||
)}
|
||||
Analyse des Résultats
|
||||
</Typography>
|
||||
|
||||
<Box sx={{ display: 'flex', gap: 2, flexWrap: 'wrap', mb: 2 }}>
|
||||
<Chip
|
||||
label={`Total: ${analysisResults.totalTests}`}
|
||||
color="primary"
|
||||
/>
|
||||
<Chip
|
||||
label={`Succès: ${analysisResults.successfulResolutions}`}
|
||||
color="success"
|
||||
/>
|
||||
<Chip
|
||||
label={`Échecs: ${analysisResults.failedResolutions}`}
|
||||
color="error"
|
||||
/>
|
||||
<Chip
|
||||
label={`VWB: ${analysisResults.vwbSteps}`}
|
||||
color="info"
|
||||
/>
|
||||
<Chip
|
||||
label={`Taux: ${analysisResults.successRate.toFixed(1)}%`}
|
||||
color={analysisResults.successRate === 100 ? 'success' : 'warning'}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
{analysisResults.failedResolutions > 0 && (
|
||||
<Alert severity="error" sx={{ mt: 2 }}>
|
||||
<Typography variant="body2">
|
||||
{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.
|
||||
</Typography>
|
||||
</Alert>
|
||||
)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
)}
|
||||
|
||||
{/* Configuration disponible */}
|
||||
<Accordion sx={{ mb: 3 }}>
|
||||
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
|
||||
<Typography variant="h6">
|
||||
Configuration stepParametersConfig Disponible
|
||||
</Typography>
|
||||
</AccordionSummary>
|
||||
<AccordionDetails>
|
||||
<TableContainer component={Paper}>
|
||||
<Table size="small">
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableCell>Type d'Étape</TableCell>
|
||||
<TableCell>Nombre de Paramètres</TableCell>
|
||||
<TableCell>Paramètres</TableCell>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{Object.entries(stepParametersConfig).map(([stepType, config]) => (
|
||||
<TableRow key={stepType}>
|
||||
<TableCell>
|
||||
<Chip label={stepType} size="small" />
|
||||
</TableCell>
|
||||
<TableCell>{config.length}</TableCell>
|
||||
<TableCell>
|
||||
{config.map(param => param.name).join(', ')}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
</AccordionDetails>
|
||||
</Accordion>
|
||||
|
||||
{/* Résultats des tests */}
|
||||
{testResults.length > 0 && (
|
||||
<Accordion>
|
||||
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
|
||||
<Typography variant="h6">
|
||||
Résultats Détaillés des Tests ({testResults.length})
|
||||
</Typography>
|
||||
</AccordionSummary>
|
||||
<AccordionDetails>
|
||||
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
|
||||
{testResults.map((result, index) => (
|
||||
<Card key={index} variant="outlined">
|
||||
<CardContent>
|
||||
<Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 2 }}>
|
||||
<Typography variant="h6">
|
||||
Test: {result.stepType}
|
||||
</Typography>
|
||||
<Chip
|
||||
label={result.resolvedConfigLength > 0 ? 'SUCCÈS' : 'ÉCHEC'}
|
||||
color={result.resolvedConfigLength > 0 ? 'success' : 'error'}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
<Box sx={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))', gap: 2 }}>
|
||||
<Box>
|
||||
<Typography variant="body2" color="text.secondary">
|
||||
Configuration Directe
|
||||
</Typography>
|
||||
<Typography variant="body1">
|
||||
{result.directConfigLength} paramètres
|
||||
</Typography>
|
||||
</Box>
|
||||
|
||||
<Box>
|
||||
<Typography variant="body2" color="text.secondary">
|
||||
Configuration Résolue
|
||||
</Typography>
|
||||
<Typography variant="body1">
|
||||
{result.resolvedConfigLength} paramètres
|
||||
</Typography>
|
||||
</Box>
|
||||
|
||||
<Box>
|
||||
<Typography variant="body2" color="text.secondary">
|
||||
Est Action VWB
|
||||
</Typography>
|
||||
<Typography variant="body1">
|
||||
{result.isVWBStep ? 'Oui' : 'Non'}
|
||||
</Typography>
|
||||
</Box>
|
||||
|
||||
<Box>
|
||||
<Typography variant="body2" color="text.secondary">
|
||||
Config Existe
|
||||
</Typography>
|
||||
<Typography variant="body1">
|
||||
{result.configExists ? 'Oui' : 'Non'}
|
||||
</Typography>
|
||||
</Box>
|
||||
</Box>
|
||||
|
||||
{result.resolvedConfigLength === 0 && result.configExists && (
|
||||
<Alert severity="error" sx={{ mt: 2 }}>
|
||||
<Typography variant="body2">
|
||||
🚨 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.
|
||||
</Typography>
|
||||
</Alert>
|
||||
)}
|
||||
|
||||
<Accordion sx={{ mt: 2 }}>
|
||||
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
|
||||
<Typography variant="body2">
|
||||
Détails Techniques
|
||||
</Typography>
|
||||
</AccordionSummary>
|
||||
<AccordionDetails>
|
||||
<Box component="pre" sx={{
|
||||
fontSize: '0.75rem',
|
||||
bgcolor: '#f5f5f5',
|
||||
p: 1,
|
||||
borderRadius: 1,
|
||||
overflow: 'auto',
|
||||
}}>
|
||||
{JSON.stringify(result, null, 2)}
|
||||
</Box>
|
||||
</AccordionDetails>
|
||||
</Accordion>
|
||||
</CardContent>
|
||||
</Card>
|
||||
))}
|
||||
</Box>
|
||||
</AccordionDetails>
|
||||
</Accordion>
|
||||
)}
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
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())
|
||||
Reference in New Issue
Block a user