#!/usr/bin/env python3 """ Test du WorkflowMatcher - VĂ©rifie la correspondance entre actions et workflows """ import sys from pathlib import Path sys.path.insert(0, str(Path(__file__).parent / "geniusia2")) from core.logger import Logger from core.config import get_config from core.workflow_matcher import WorkflowMatcher, WorkflowMatch def test_perfect_match(): """Test avec un match parfait""" print("\n" + "="*60) print("đŸ§Ș TEST 1: Match parfait") print("="*60) logger = Logger() config = get_config() matcher = WorkflowMatcher(logger, config) # Actions courantes (2 premiĂšres Ă©tapes d'un workflow) session_actions = [ { "action_type": "click", "position": [100, 100], "window": "Calculatrice" }, { "action_type": "type", "position": [150, 150], "window": "Calculatrice" } ] # Workflow connu (3 Ă©tapes) workflow = { "workflow_id": "calc_001", "name": "Calcul simple", "steps": [ { "action_type": "click", "position": [100, 100], "window": "Calculatrice" }, { "action_type": "type", "position": [150, 150], "window": "Calculatrice" }, { "action_type": "click", "position": [200, 200], "window": "Calculatrice" } ] } # Matcher matches = matcher.match_current_session(session_actions, [workflow]) print(f"\n📊 RĂ©sultats:") print(f" Matches trouvĂ©s: {len(matches)}") if matches: match = matches[0] print(f" Workflow: {match.workflow_name}") print(f" Confiance: {match.confidence:.2%}") print(f" Étapes matchĂ©es: {match.matched_steps}/{match.total_steps}") print(f" Étapes restantes: {len(match.remaining_steps)}") assert match.confidence >= 0.8, f"Confiance trop faible: {match.confidence}" assert match.matched_steps == 2, f"Devrait matcher 2 Ă©tapes, trouvĂ© {match.matched_steps}" assert len(match.remaining_steps) == 1, f"Devrait rester 1 Ă©tape, trouvĂ© {len(match.remaining_steps)}" print(f"\n✅ Match parfait dĂ©tectĂ© !") return True else: print(f"\n❌ Aucun match trouvĂ©") return False def test_position_tolerance(): """Test avec tolĂ©rance de position""" print("\n" + "="*60) print("đŸ§Ș TEST 2: TolĂ©rance de position") print("="*60) logger = Logger() config = get_config() matcher = WorkflowMatcher(logger, config) # Actions avec positions lĂ©gĂšrement dĂ©calĂ©es session_actions = [ { "action_type": "click", "position": [120, 110], # DĂ©calĂ© de 20px "window": "Firefox" }, { "action_type": "type", "position": [165, 155], # DĂ©calĂ© de 15px "window": "Firefox" } ] # Workflow avec positions originales workflow = { "workflow_id": "firefox_001", "name": "Recherche Firefox", "steps": [ { "action_type": "click", "position": [100, 100], "window": "Firefox" }, { "action_type": "type", "position": [150, 150], "window": "Firefox" }, { "action_type": "click", "position": [300, 200], "window": "Firefox" } ] } matches = matcher.match_current_session(session_actions, [workflow]) print(f"\n📊 RĂ©sultats:") print(f" Matches trouvĂ©s: {len(matches)}") if matches: match = matches[0] print(f" Workflow: {match.workflow_name}") print(f" Confiance: {match.confidence:.2%}") print(f" Étapes matchĂ©es: {match.matched_steps}/{match.total_steps}") # Avec tolĂ©rance de 50px, devrait matcher assert match.confidence >= 0.7, f"Confiance trop faible avec tolĂ©rance: {match.confidence}" print(f"\n✅ TolĂ©rance de position fonctionne !") return True else: print(f"\n❌ Aucun match trouvĂ© (tolĂ©rance insuffisante ?)") return False def test_best_match_selection(): """Test de sĂ©lection du meilleur match""" print("\n" + "="*60) print("đŸ§Ș TEST 3: SĂ©lection du meilleur match") print("="*60) logger = Logger() config = get_config() matcher = WorkflowMatcher(logger, config) # Actions courantes session_actions = [ { "action_type": "click", "position": [100, 100], "window": "OnlyOffice" }, { "action_type": "type", "position": [150, 150], "window": "OnlyOffice" } ] # Plusieurs workflows possibles workflows = [ { "workflow_id": "office_001", "name": "Workflow A (bon match)", "steps": [ { "action_type": "click", "position": [100, 100], "window": "OnlyOffice" }, { "action_type": "type", "position": [150, 150], "window": "OnlyOffice" }, { "action_type": "click", "position": [200, 200], "window": "OnlyOffice" } ] }, { "workflow_id": "office_002", "name": "Workflow B (mauvais match)", "steps": [ { "action_type": "scroll", # Type diffĂ©rent "position": [100, 100], "window": "OnlyOffice" }, { "action_type": "click", "position": [150, 150], "window": "OnlyOffice" } ] } ] matches = matcher.match_current_session(session_actions, workflows) print(f"\n📊 RĂ©sultats:") print(f" Matches trouvĂ©s: {len(matches)}") for i, match in enumerate(matches): print(f"\n Match {i+1}:") print(f" Workflow: {match.workflow_name}") print(f" Confiance: {match.confidence:.2%}") # Trouver le meilleur best = matcher.find_best_match(matches) if best: print(f"\n🏆 Meilleur match:") print(f" Workflow: {best.workflow_name}") print(f" Confiance: {best.confidence:.2%}") # Le meilleur devrait ĂȘtre le Workflow A assert best.workflow_id == "office_001", f"Mauvais workflow sĂ©lectionnĂ©: {best.workflow_id}" assert best.confidence >= 0.8, f"Confiance insuffisante: {best.confidence}" # VĂ©rifier les dĂ©tails details = matcher.get_match_details(best) print(f"\n📋 DĂ©tails:") print(f" Étapes matchĂ©es: {details['matched_steps']}/{details['total_steps']}") print(f" ComplĂ©tion: {details['completion_percentage']:.1f}%") print(f" Prochaines Ă©tapes: {len(details['next_steps_preview'])}") print(f"\n✅ Meilleur match correctement sĂ©lectionnĂ© !") return True else: print(f"\n❌ Aucun match au-dessus du seuil") return False def test_no_match(): """Test sans correspondance""" print("\n" + "="*60) print("đŸ§Ș TEST 4: Aucune correspondance") print("="*60) logger = Logger() config = get_config() matcher = WorkflowMatcher(logger, config) # Actions complĂštement diffĂ©rentes session_actions = [ { "action_type": "scroll", "position": [500, 500], "window": "Terminal" } ] # Workflow diffĂ©rent workflow = { "workflow_id": "calc_001", "name": "Calcul", "steps": [ { "action_type": "click", "position": [100, 100], "window": "Calculatrice" } ] } matches = matcher.match_current_session(session_actions, [workflow]) best = matcher.find_best_match(matches) print(f"\n📊 RĂ©sultats:") print(f" Matches trouvĂ©s: {len(matches)}") print(f" Meilleur match: {best}") # Ne devrait pas trouver de match au-dessus du seuil assert best is None, "Ne devrait pas trouver de match" print(f"\n✅ Aucun faux positif !") return True def main(): """ExĂ©cute tous les tests""" print("\n" + "="*60) print("🚀 TEST DU WORKFLOW MATCHER") print("="*60) results = [] try: results.append(("Match parfait", test_perfect_match())) except Exception as e: print(f"\n❌ ERREUR Test 1: {e}") import traceback traceback.print_exc() results.append(("Match parfait", False)) try: results.append(("TolĂ©rance position", test_position_tolerance())) except Exception as e: print(f"\n❌ ERREUR Test 2: {e}") import traceback traceback.print_exc() results.append(("TolĂ©rance position", False)) try: results.append(("Meilleur match", test_best_match_selection())) except Exception as e: print(f"\n❌ ERREUR Test 3: {e}") import traceback traceback.print_exc() results.append(("Meilleur match", False)) try: results.append(("Aucune correspondance", test_no_match())) except Exception as e: print(f"\n❌ ERREUR Test 4: {e}") import traceback traceback.print_exc() results.append(("Aucune correspondance", False)) # RĂ©sumĂ© print("\n" + "="*60) print("📊 RÉSUMÉ DES TESTS") print("="*60) for name, success in results: status = "✅" if success else "❌" print(f"{status} {name}") total = len(results) passed = sum(1 for _, success in results if success) print(f"\n📈 Score: {passed}/{total} tests rĂ©ussis") if passed == total: print("\n🎉 TOUS LES TESTS SONT PASSÉS !") print("\n💡 Prochaine Ă©tape:") print(" IntĂ©grer WorkflowMatcher dans SuggestionManager") return 0 else: print(f"\n⚠ {total - passed} test(s) Ă©chouĂ©(s)") return 1 if __name__ == "__main__": sys.exit(main())