Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion workflows/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,14 @@ python cli.py run-workflow-no-ai my_workflow.json
- **10-100x Faster**: 5-10s vs 20-40s for LLM-based
- **90% Cheaper**: Minimal LLM usage

### 🎯 Variables in Workflows
### 🎯 Semantic-Only Multi-Strategy Element Finding
- **No CSS/XPath**: 100% semantic strategies (text, role, ARIA, placeholder, etc.)
- **7 Fallback Strategies**: text_exact → role_text → aria_label → placeholder → title → alt_text → text_fuzzy
- **Works WITH Browser-Use**: Finds element index in DOM state, then uses browser-use's controller
- **Fast & Robust**: Direct index lookup when strategies match, falls back to AI when needed
- **Human-Readable**: Workflow YAML contains semantic strategies, not brittle selectors

### 🔄 Variables in Workflows
- **Reusable Workflows**: Parameterize dynamic values
- **Semantic Targeting**: Use `{variable}` in `target_text`
- **Auto-Extraction**: LLM suggests variables automatically
Expand Down
86 changes: 86 additions & 0 deletions workflows/tests/run_all_tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
"""
Run all unit tests for the semantic-only workflow system.

This script runs all test modules and provides a summary.
"""

import subprocess
import sys


def run_test_file(test_file):
"""Run a single test file and return (passed, failed)"""
print(f'\n{"=" * 80}')
print(f'Running {test_file}')
print(f'{"=" * 80}')

result = subprocess.run(['uv', 'run', 'python', f'workflows/tests/{test_file}'], capture_output=True, text=True)

# Print output
print(result.stdout)
if result.stderr:
print(result.stderr)

# Parse results from output
for line in result.stdout.split('\n'):
if 'Test Results:' in line:
# Extract passed and failed counts
# Format: "Test Results: X passed, Y failed"
parts = line.split(':')[1].strip().split(',')
passed = int(parts[0].split()[0])
failed = int(parts[1].split()[0])
return (passed, failed)

# If we couldn't parse, check exit code
if result.returncode == 0:
return (1, 0) # Assume some tests passed
else:
return (0, 1) # Assume some tests failed


def main():
"""Run all tests and provide summary"""
test_files = [
'test_selector_generator.py',
'test_element_finder.py',
'test_workflow_execution.py',
]

print('\n' + '=' * 80)
print('SEMANTIC-ONLY WORKFLOW SYSTEM - UNIT TEST SUITE')
print('=' * 80)

total_passed = 0
total_failed = 0

results = []

for test_file in test_files:
passed, failed = run_test_file(test_file)
total_passed += passed
total_failed += failed
results.append((test_file, passed, failed))

# Print summary
print('\n' + '=' * 80)
print('TEST SUITE SUMMARY')
print('=' * 80)

for test_file, passed, failed in results:
status = '✅ PASS' if failed == 0 else '❌ FAIL'
print(f'{status} {test_file:40s} {passed:3d} passed, {failed:3d} failed')

print(f'\n{"=" * 80}')
print(f'TOTAL: {total_passed} passed, {total_failed} failed')
print(f'{"=" * 80}\n')

if total_failed > 0:
print('❌ Some tests failed!')
sys.exit(1)
else:
print('✅ All tests passed!')
sys.exit(0)


if __name__ == '__main__':
main()
Loading
Loading