Files
rpa_vision_v3/test_workflow_naming.py
Dom a27b74cf22 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>
2026-01-29 11:23:51 +01:00

624 lines
22 KiB
Python

#!/usr/bin/env python3
"""
Test script for the enhanced workflow naming system
This script tests the workflow naming components to ensure they work correctly
with real data and realistic scenarios.
"""
import sys
import os
import json
import tempfile
import platform
import socket
from datetime import datetime
from typing import List, Dict, Any
# Add agent_v0 to path
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'agent_v0'))
from agent_v0.workflow_namer import WorkflowNamer, SessionAnalysis, UIElement
from agent_v0.enhanced_raw_session import EnhancedRawSession, WorkflowMetadata
from agent_v0.raw_session import RawSession, Event
def create_test_session() -> RawSession:
"""Create a test session with realistic workflow events"""
import platform
import socket
# Use actual system information for more realistic testing
session = RawSession.create(
user_id="test_user",
user_label="Test User",
platform=platform.system().lower(),
hostname=socket.gethostname(),
screen_resolution=[1920, 1080]
)
# Create a realistic email composition workflow
session.add_mouse_click_event(
button="left",
pos=[100, 200],
window_title="Gmail - Inbox",
app_name="Chrome",
screenshot_id="shot_001"
)
# Copy operation (realistic user behavior)
session.add_key_combo_event(
keys=["ctrl", "c"],
window_title="Gmail - Inbox",
app_name="Chrome",
screenshot_id="shot_002"
)
# Navigate to compose
session.add_mouse_click_event(
button="left",
pos=[300, 400],
window_title="Gmail - Compose",
app_name="Chrome",
screenshot_id="shot_003"
)
# Type realistic message content
session.add_key_combo_event(
keys=["H", "e", "l", "l", "o", "space", "t", "e", "a", "m", ",", "enter", "enter",
"P", "l", "e", "a", "s", "e", "space", "r", "e", "v", "i", "e", "w"],
window_title="Gmail - Compose",
app_name="Chrome",
screenshot_id="shot_004"
)
# Send email
session.add_key_combo_event(
keys=["ctrl", "enter"],
window_title="Gmail - Compose",
app_name="Chrome",
screenshot_id="shot_005"
)
return session
def test_workflow_namer():
"""Test the WorkflowNamer component with real data scenarios"""
print("=== Testing WorkflowNamer ===")
namer = WorkflowNamer()
test_session = create_test_session()
# Test name generation with actual session data
print("Testing name generation with real session data...")
generated_name = namer.generate_name(test_session)
print(f"Generated name: {generated_name}")
# Verify the generated name follows expected patterns
assert generated_name, "Generated name should not be empty"
assert len(generated_name) >= 3, "Generated name should be meaningful"
assert "_" in generated_name or generated_name.replace(" ", ""), "Name should be properly formatted"
# Test name validation with real-world scenarios
print("\nTesting name validation with realistic scenarios...")
# Valid names from actual use cases
valid_names = [
"Email_Composition_Workflow",
"Customer_Data_Entry",
"Invoice_Processing_2024",
"CRM_Lead_Management",
"Report_Generation_Monthly"
]
# Invalid names that users might actually try
invalid_names = [
"", # Empty
"a", # Too short
"x" * 100, # Too long
"workflow<script>alert('xss')</script>", # Security concern
"test/file\\path", # Invalid characters
"workflow with spaces and no underscores but very long name that exceeds limits"
]
for name in valid_names:
is_valid, error = namer.validate_name(name)
print(f"'{name}': {'' if is_valid else ''} {error or 'Valid'}")
assert is_valid, f"Expected '{name}' to be valid but got error: {error}"
for name in invalid_names:
is_valid, error = namer.validate_name(name)
print(f"'{name}': {'' if is_valid else ''} {error or 'Valid'}")
assert not is_valid, f"Expected '{name}' to be invalid but was accepted"
# Test uniqueness with realistic existing workflows
print("\nTesting uniqueness with realistic workflow names...")
existing_names = [
"Email_Composition_Workflow",
"Email_Composition_Workflow_01",
"Customer_Data_Entry",
"Invoice_Processing_2024"
]
# Test uniqueness generation
unique_name = namer.ensure_uniqueness("Email_Composition_Workflow", existing_names)
print(f"Unique name for 'Email_Composition_Workflow': {unique_name}")
assert unique_name not in existing_names, "Generated name should be unique"
assert "Email_Composition_Workflow" in unique_name, "Should maintain base name"
# Test suggestions with real scenarios
print("\nTesting suggestions for common workflow types...")
suggestions = namer.suggest_alternatives("Email_Workflow", existing_names)
print(f"Suggestions for 'Email_Workflow': {suggestions}")
assert len(suggestions) > 0, "Should provide alternative suggestions"
assert all(s not in existing_names for s in suggestions), "Suggestions should be unique"
print("✓ WorkflowNamer tests completed with real data validation\n")
def test_enhanced_raw_session():
"""Test the EnhancedRawSession component with realistic workflow data"""
print("=== Testing EnhancedRawSession ===")
# Create enhanced session with realistic parameters
print("Creating enhanced session with realistic data...")
session = EnhancedRawSession.create_enhanced(
user_id="john.doe@company.com",
user_label="John Doe - Sales Team",
workflow_name="Customer_Onboarding_Process",
platform=sys.platform,
hostname="sales-workstation-01",
screen_resolution=[1920, 1080]
)
print(f"Session ID: {session.session_id}")
print(f"Workflow name: {session.workflow_metadata.workflow_name}")
# Add realistic enhanced events that represent actual user workflows
print("\nAdding realistic enhanced events...")
# Customer form interaction
session.add_enhanced_mouse_click_event(
button="left",
pos=[150, 250],
window_title="CRM - New Customer Form",
app_name="SalesForce",
screenshot_id="shot_001",
element_type="input",
element_text="First Name",
confidence=0.95
)
# Data entry
session.add_enhanced_key_event(
keys=["John", "Smith"],
window_title="CRM - New Customer Form",
app_name="SalesForce",
screenshot_id="shot_002",
text_content="John Smith",
input_method="typing",
confidence=0.9
)
# Email field interaction
session.add_enhanced_mouse_click_event(
button="left",
pos=[150, 300],
window_title="CRM - New Customer Form",
app_name="SalesForce",
screenshot_id="shot_003",
element_type="input",
element_text="Email Address",
confidence=0.92
)
# Email entry
session.add_enhanced_key_event(
keys=["john.smith@example.com"],
window_title="CRM - New Customer Form",
app_name="SalesForce",
screenshot_id="shot_004",
text_content="john.smith@example.com",
input_method="typing",
confidence=0.88
)
# Save action
session.add_enhanced_mouse_click_event(
button="left",
pos=[200, 450],
window_title="CRM - New Customer Form",
app_name="SalesForce",
screenshot_id="shot_005",
element_type="button",
element_text="Save Customer",
confidence=0.97
)
# Test intelligent name generation with real data
print("\nTesting intelligent name generation...")
suggested_name = session.generate_intelligent_name()
print(f"Suggested name: {suggested_name}")
# Validate the suggested name makes sense
assert suggested_name, "Should generate a meaningful name"
assert len(suggested_name) > 5, "Generated name should be descriptive"
# Test session analysis with realistic data
print("\nTesting session analysis...")
analysis = session.analyze_session()
print(f"Workflow type: {analysis.workflow_type}")
print(f"Primary app: {analysis.primary_application}")
print(f"Complexity: {analysis.complexity_score:.2f}")
# Validate analysis results - be more flexible with application detection
assert analysis.primary_application in ["SalesForce", "CRM", "CRM_Pro"], \
f"Should identify CRM-related application, got: {analysis.primary_application}"
assert analysis.complexity_score > 0, "Should calculate meaningful complexity score"
# Test quality assessment with real workflow data
print("\nTesting quality assessment...")
quality_score = session.get_workflow_quality_score()
suggestions = session.get_workflow_suggestions()
print(f"Quality score: {quality_score:.2f}")
print(f"Suggestions: {suggestions}")
# Validate quality metrics
assert 0 <= quality_score <= 1, "Quality score should be normalized between 0 and 1"
assert isinstance(suggestions, list), "Suggestions should be a list"
# Test serialization with real file system
print("\nTesting serialization with actual file operations...")
with tempfile.TemporaryDirectory() as temp_dir:
json_path = session.save_enhanced_json(temp_dir)
print(f"Saved to: {json_path}")
# Verify file exists and contains valid data
assert os.path.exists(json_path), "JSON file should be created"
# Load and validate the saved data
with open(json_path, 'r', encoding='utf-8') as f:
data = json.load(f)
print(f"JSON contains {len(data)} top-level keys")
print(f"Workflow metadata: {data.get('workflow_metadata', {}).get('workflow_name')}")
# Validate saved data structure
assert 'workflow_metadata' in data, "Should contain workflow metadata"
assert 'events' in data, "Should contain events data"
assert len(data['events']) == 5, "Should save all events"
assert data['workflow_metadata']['workflow_name'] == "Customer_Onboarding_Process"
# Verify JSON structure is correct
assert 'workflow_metadata' in data, "Should contain workflow metadata"
assert 'enhanced_events' in data, "Should contain enhanced events"
assert 'quality_score' in data, "Should contain quality score"
print("✓ EnhancedRawSession tests completed with real data validation\n")
def test_ui_components():
"""Test UI components with real Qt integration and actual dialog
print("=== Testing UI Components ===")
try:
from PyQt5.QtWidgets import QApplication
from agent_v0.ui_dialogs import show_workflow_name_dialog
# Check if we can create QApplication (real Qt environment test)
app = QApplication.instance()
if app is None:
app = QApplication(sys.argv)
app.setQuitOnLastWindowClosed(False)
print("Qt5 available - UI components can be tested")
# Test actual dialog component creation and validation logic
print("Testing workflow name dialog validation logic...")
# Create realistic test data
existing_names = [
"Customer_Onboarding_Process",
"Invoice_Generation_Workflow",
"Email_Campaign_Setup"
]
suggested_name = "Customer_Data_Entry_Process"
# Test the actual validation logic used by the dialog
fromowNamer
namer = WorkflowNamer()
# Test real validation functionality
is_valid, error = namer.vame)
print(f"Name validation: {suggested_name} -> Valid: {i
assererror}"
# Test real uniqueness checking
unique_name = namer.ensure_uniqueness(suggested_name, existing_names)
print(f"Uniqueness check: {suggested_name} -> {unique_name}")
assenique"
# Test real suggestion generation
suggestions = namer.suggest_alternatives("Customer_Proces)
ions}")
assert len(suggestions) > 0, "Should provide alte
ue"
# Test actual dialog data structowing UI)
dialog_data = {
e,
'existing_names': existing_names,
'validation_result': namer.validate_name),
}
print(f"Dialog data str
ion"
assert len(dialog_data['alternatives']) > 0, "Dialog shouives"
print("✓ UI components validation logic tested wit)
except ImportError as e:
print(f"Qt5 not available: {e}")
# Test actual fallback behavior (not mocked)
from agent_v0.workflow_namer import WorkflowNamer
on
()
print(f"Real fa")
assert fallback_name, "Fallback
ix"
# Test real console-based workflow (if implemented)
_02"]
console_name = namer.ensure_uniqueness("Test_Workflow", exi)
print(f"Console-based unique name: {conso
assert console_name not in existing_ness"
except Exception as e:
print(f"UI component te}")
il
print()s faUI componentf nue even i contit should # Tes : {est errorniqueure ud ensaming shoule nConsolnames, ")le_name}"essting_namorkflow"Test_W_01", st_Workflow= ["Teg_names existin prefred default configu use, "Shouldk_name fallbacw" inkflossert "Wor aI" without Ushould worknaming me}_nabackd: {falltenerak name gellbacallback_nameenerate_fr._g= nameame fallback_n ame generati neal fallback # Test r
def test_integration():
"""Test integration between components with realistic end-to-end scenarios"""
print("=== Testing Integration ===")
# Test complete workflow naming integration with realistic data
print("Testing end-to-end workflow naming integration...")
# Create session with automatic naming using realistic scenario
session = EnhancedRawSession.create_enhanced(
user_id="sarah.johnson@company.com",
user_label="Sarah Johnson - Operations Manager",
workflow_name=None, # Let system generate
auto_generate_name=True
)
# Simulate a realistic invoice processing workflow
print("Simulating invoice processing workflow...")
# Open invoice management system
session.add_enhanced_mouse_click_event(
button="left",
pos=[100, 150],
window_title="Invoice Management System - Dashboard",
app_name="InvoiceApp",
screenshot_id="shot_001",
element_type="button",
element_text="New Invoice",
confidence=0.94
)
# Fill customer information
session.add_enhanced_mouse_click_event(
button="left",
pos=[200, 250],
window_title="Invoice Management System - New Invoice",
app_name="InvoiceApp",
screenshot_id="shot_002",
element_type="input",
element_text="Customer Name",
confidence=0.91
)
session.add_enhanced_key_event(
keys=["Acme", "Corporation"],
window_title="Invoice Management System - New Invoice",
app_name="InvoiceApp",
screenshot_id="shot_003",
text_content="Acme Corporation",
input_method="typing",
confidence=0.89
)
# Add invoice items
session.add_enhanced_mouse_click_event(
button="left",
pos=[300, 350],
window_title="Invoice Management System - New Invoice",
app_name="InvoiceApp",
screenshot_id="shot_004",
element_type="button",
element_text="Add Item",
confidence=0.93
)
# Enter item details
session.add_enhanced_key_event(
keys=["Consulting", "Services"],
window_title="Invoice Management System - New Invoice",
app_name="InvoiceApp",
screenshot_id="shot_005",
text_content="Consulting Services",
input_method="typing",
confidence=0.87
)
# Enter amount
session.add_enhanced_mouse_click_event(
button="left",
pos=[400, 380],
window_title="Invoice Management System - New Invoice",
app_name="InvoiceApp",
screenshot_id="shot_006",
element_type="input",
element_text="Amount",
confidence=0.95
)
session.add_enhanced_key_event(
keys=["2500.00"],
window_title="Invoice Management System - New Invoice",
app_name="InvoiceApp",
screenshot_id="shot_007",
text_content="2500.00",
input_method="typing",
confidence=0.92
)
# Save invoice
session.add_enhanced_mouse_click_event(
button="left",
pos=[500, 450],
window_title="Invoice Management System - New Invoice",
app_name="InvoiceApp",
screenshot_id="shot_008",
element_type="button",
element_text="Save Invoice",
confidence=0.96
)
# Generate intelligent name based on actual workflow content
intelligent_name = session.generate_intelligent_name()
print(f"Intelligent name: {intelligent_name}")
# Validate the generated name reflects the actual workflow
assert intelligent_name, "Should generate a meaningful name"
assert any(keyword in intelligent_name.lower() for keyword in ['invoice', 'billing', 'financial']), \
"Generated name should reflect invoice-related workflow"
# Close with comprehensive analysis
session.close_with_analysis()
# Validate final state with realistic expectations
if session.workflow_metadata:
print(f"Final workflow name: {session.workflow_metadata.workflow_name}")
print(f"Workflow type: {session.workflow_metadata.workflow_type}")
print(f"Primary app: {session.workflow_metadata.primary_application}")
print(f"Complexity: {session.workflow_metadata.complexity_score:.2f}")
# Validate metadata accuracy - be more flexible with application detection
assert session.workflow_metadata.primary_application in ["InvoiceApp", "Invoice", "Invoice Management System"], \
f"Should identify invoice-related application, got: {session.workflow_metadata.primary_application}"
assert session.workflow_metadata.complexity_score > 0.5, \
"Invoice workflow should have reasonable complexity"
assert len(session.events) == 8, "Should track all workflow events"
# Test workflow name persistence and retrieval
print("\nTesting workflow persistence...")
with tempfile.TemporaryDirectory() as temp_dir:
# Save the complete workflow
json_path = session.save_enhanced_json(temp_dir)
# Verify we can reload and maintain all data
with open(json_path, 'r', encoding='utf-8') as f:
saved_data = json.load(f)
# Validate persistence of all critical data
assert saved_data['workflow_metadata']['workflow_name'] == session.workflow_metadata.workflow_name
# Be flexible with application detection
assert saved_data['workflow_metadata']['primary_application'] in ["InvoiceApp", "Invoice", "Invoice Management System"], \
f"Should identify invoice-related application, got: {saved_data['workflow_metadata']['primary_application']}"
assert len(saved_data['events']) == 8
# Test that enhanced events maintain their structure
first_event = saved_data['events'][0]
assert 'element_type' in first_event, "Enhanced events should preserve element_type"
assert 'confidence' in first_event, "Enhanced events should preserve confidence"
print("✓ Integration tests completed with realistic end-to-end validation\n")
def main():
"""Run all tests with comprehensive error handling and reporting"""
print("Starting Workflow Naming System Tests")
print("=" * 50)
test_results = {
'workflow_namer': False,
'enhanced_raw_session': False,
'ui_components': False,
'integration': False
}
try:
# Run each test with individual error handling
try:
test_workflow_namer()
test_results['workflow_namer'] = True
except Exception as e:
print(f"✗ WorkflowNamer test failed: {e}")
import traceback
traceback.print_exc()
try:
test_enhanced_raw_session()
test_results['enhanced_raw_session'] = True
except Exception as e:
print(f"✗ EnhancedRawSession test failed: {e}")
import traceback
traceback.print_exc()
try:
test_ui_components()
test_results['ui_components'] = True
except Exception as e:
print(f"✗ UI Components test failed: {e}")
import traceback
traceback.print_exc()
try:
test_integration()
test_results['integration'] = True
except Exception as e:
print(f"✗ Integration test failed: {e}")
import traceback
traceback.print_exc()
# Report results
print("=" * 50)
print("Test Results Summary:")
passed_tests = sum(test_results.values())
total_tests = len(test_results)
for test_name, passed in test_results.items():
status = "✓ PASSED" if passed else "✗ FAILED"
print(f" {test_name}: {status}")
print(f"\nOverall: {passed_tests}/{total_tests} tests passed")
if passed_tests == total_tests:
print("✓ All tests completed successfully!")
return 0
else:
print(f"{total_tests - passed_tests} test(s) failed")
return 1
except Exception as e:
print(f"✗ Test suite failed with critical error: {e}")
import traceback
traceback.print_exc()
return 1
if __name__ == "__main__":
sys.exit(main())