"""
🤖 Fagun Browser Automation Testing Agent - Enhanced AI Testing Engine
====================================================================
Enhanced AI testing engine that aggressively finds errors, bugs, and issues
with comprehensive test scenarios and intelligent bug detection.
Author: Mejbaur Bahar Fagun
Role: Software Engineer in Test
LinkedIn: https://www.linkedin.com/in/mejbaur/
"""
import asyncio
import random
import string
from typing import List, Dict, Any, Optional
from playwright.async_api import Page, Locator
import logging
from dataclasses import dataclass
from enum import Enum
logger = logging.getLogger(__name__)
class BugSeverity(Enum):
"""Bug severity levels."""
CRITICAL = "critical"
HIGH = "high"
MEDIUM = "medium"
LOW = "low"
INFO = "info"
@dataclass
class BugReport:
"""Bug report structure."""
title: str
severity: BugSeverity
description: str
steps_to_reproduce: List[str]
expected_behavior: str
actual_behavior: str
url: str
element_info: Dict[str, Any]
recommendations: List[str]
class EnhancedAITestingEngine:
"""Enhanced AI testing engine with aggressive bug finding capabilities."""
def __init__(self):
self.bugs_found: List[BugReport] = []
self.test_scenarios = self._load_test_scenarios()
self.bug_patterns = self._load_bug_patterns()
self.performance_thresholds = self._load_performance_thresholds()
def _load_test_scenarios(self) -> Dict[str, List[Dict[str, Any]]]:
"""Load comprehensive test scenarios."""
return {
"navigation": [
{"action": "rapid_navigation", "description": "Rapidly navigate between pages"},
{"action": "back_forward", "description": "Test browser back/forward buttons"},
{"action": "refresh_test", "description": "Test page refresh functionality"},
{"action": "url_manipulation", "description": "Test URL manipulation and direct access"}
],
"form_testing": [
{"action": "empty_submission", "description": "Submit forms with empty fields"},
{"action": "invalid_data", "description": "Submit forms with invalid data"},
{"action": "sql_injection", "description": "Test for SQL injection vulnerabilities"},
{"action": "xss_attempts", "description": "Test for XSS vulnerabilities"},
{"action": "large_data", "description": "Submit forms with large amounts of data"},
{"action": "special_characters", "description": "Test with special characters"},
{"action": "unicode_testing", "description": "Test with Unicode characters"},
{"action": "script_injection", "description": "Test for script injection"}
],
"ui_testing": [
{"action": "responsive_test", "description": "Test responsive design"},
{"action": "accessibility_test", "description": "Test accessibility features"},
{"action": "hover_effects", "description": "Test hover effects and interactions"},
{"action": "click_areas", "description": "Test clickable areas and buttons"},
{"action": "scroll_behavior", "description": "Test scrolling behavior"},
{"action": "zoom_testing", "description": "Test zoom functionality"},
{"action": "keyboard_navigation", "description": "Test keyboard navigation"}
],
"performance": [
{"action": "load_time_test", "description": "Test page load times"},
{"action": "resource_loading", "description": "Test resource loading performance"},
{"action": "memory_usage", "description": "Monitor memory usage"},
{"action": "cpu_usage", "description": "Monitor CPU usage"},
{"action": "network_latency", "description": "Test network latency"}
],
"security": [
{"action": "csrf_test", "description": "Test for CSRF vulnerabilities"},
{"action": "clickjacking", "description": "Test for clickjacking vulnerabilities"},
{"action": "session_management", "description": "Test session management"},
{"action": "authentication", "description": "Test authentication mechanisms"},
{"action": "authorization", "description": "Test authorization controls"}
]
}
def _load_bug_patterns(self) -> Dict[str, List[str]]:
"""Load bug detection patterns."""
return {
"ui_bugs": [
"Element not visible",
"Element not clickable",
"Layout broken",
"Text overflow",
"Image not loading",
"Button not responding",
"Form validation missing",
"Error message not displayed",
"Loading state not handled",
"Responsive design issues"
],
"functional_bugs": [
"Function not working",
"Data not saved",
"Validation bypassed",
"Error not handled",
"State not maintained",
"Navigation broken",
"Search not working",
"Filter not applied",
"Sort not working",
"Pagination broken"
],
"performance_bugs": [
"Page load too slow",
"Memory leak detected",
"CPU usage high",
"Network timeout",
"Resource not optimized",
"Caching issues",
"Database slow query",
"API response slow",
"Image not optimized",
"JavaScript blocking"
],
"security_bugs": [
"SQL injection possible",
"XSS vulnerability",
"CSRF token missing",
"Authentication bypass",
"Authorization issue",
"Data exposure",
"Session hijacking",
"Clickjacking possible",
"Input not sanitized",
"Error information leaked"
]
}
def _load_performance_thresholds(self) -> Dict[str, float]:
"""Load performance thresholds."""
return {
"page_load_time": 3.0, # seconds
"element_interaction_time": 1.0, # seconds
"form_submission_time": 2.0, # seconds
"navigation_time": 1.5, # seconds
"memory_usage_mb": 100.0, # MB
"cpu_usage_percent": 80.0, # percentage
}
async def run_comprehensive_testing(self, page: Page) -> List[BugReport]:
"""Run comprehensive testing with all AI agents."""
logger.info("🤖 Starting comprehensive AI testing...")
# Clear previous bugs
self.bugs_found.clear()
# Run all test scenarios
await self._test_navigation_scenarios(page)
await self._test_form_scenarios(page)
await self._test_ui_scenarios(page)
await self._test_performance_scenarios(page)
await self._test_security_scenarios(page)
logger.info(f"🔍 Found {len(self.bugs_found)} bugs/issues during testing")
return self.bugs_found
async def _test_navigation_scenarios(self, page: Page):
"""Test navigation scenarios."""
logger.info("🧭 Testing navigation scenarios...")
try:
# Test rapid navigation
await self._rapid_navigation_test(page)
# Test back/forward
await self._back_forward_test(page)
# Test refresh
await self._refresh_test(page)
# Test URL manipulation
await self._url_manipulation_test(page)
except Exception as e:
logger.error(f"Navigation testing error: {e}")
async def _test_form_scenarios(self, page: Page):
"""Test form scenarios."""
logger.info("📝 Testing form scenarios...")
try:
# Find all forms
forms = await page.query_selector_all('form')
for form in forms:
# Test empty submission
await self._test_empty_form_submission(form, page)
# Test invalid data
await self._test_invalid_form_data(form, page)
# Test SQL injection
await self._test_sql_injection_forms(form, page)
# Test XSS attempts
await self._test_xss_forms(form, page)
# Test large data
await self._test_large_form_data(form, page)
# Test special characters
await self._test_special_characters(form, page)
except Exception as e:
logger.error(f"Form testing error: {e}")
async def _test_ui_scenarios(self, page: Page):
"""Test UI scenarios."""
logger.info("🎨 Testing UI scenarios...")
try:
# Test responsive design
await self._test_responsive_design(page)
# Test accessibility
await self._test_accessibility(page)
# Test hover effects
await self._test_hover_effects(page)
# Test clickable areas
await self._test_clickable_areas(page)
# Test scrolling
await self._test_scrolling_behavior(page)
except Exception as e:
logger.error(f"UI testing error: {e}")
async def _test_performance_scenarios(self, page: Page):
"""Test performance scenarios."""
logger.info("⚡ Testing performance scenarios...")
try:
# Test page load time
await self._test_page_load_time(page)
# Test resource loading
await self._test_resource_loading(page)
# Test memory usage
await self._test_memory_usage(page)
# Test network performance
await self._test_network_performance(page)
except Exception as e:
logger.error(f"Performance testing error: {e}")
async def _test_security_scenarios(self, page: Page):
"""Test security scenarios."""
logger.info("🔒 Testing security scenarios...")
try:
# Test CSRF
await self._test_csrf_vulnerabilities(page)
# Test clickjacking
await self._test_clickjacking(page)
# Test session management
await self._test_session_management(page)
# Test authentication
await self._test_authentication(page)
except Exception as e:
logger.error(f"Security testing error: {e}")
async def _rapid_navigation_test(self, page: Page):
"""Test rapid navigation between pages."""
try:
# Get all links
links = await page.query_selector_all('a[href]')
if len(links) > 3:
# Click first 3 links rapidly
for i in range(min(3, len(links))):
try:
await links[i].click()
await page.wait_for_timeout(500) # Short wait
# Check for errors
if await self._check_for_errors(page):
self._add_bug_report(
title="Rapid Navigation Error",
severity=BugSeverity.MEDIUM,
description="Error occurred during rapid navigation",
steps_to_reproduce=["Navigate rapidly between pages", "Click multiple links quickly"],
expected_behavior="Navigation should work smoothly",
actual_behavior="Error occurred during navigation",
url=page.url,
element_info={"link_index": i},
recommendations=["Add loading states", "Implement proper error handling"]
)
except Exception as e:
self._add_bug_report(
title="Navigation Failure",
severity=BugSeverity.HIGH,
description=f"Failed to navigate: {str(e)}",
steps_to_reproduce=["Click on navigation link", "Observe error"],
expected_behavior="Navigation should work",
actual_behavior=f"Navigation failed: {str(e)}",
url=page.url,
element_info={"link_index": i},
recommendations=["Fix navigation logic", "Add error handling"]
)
except Exception as e:
logger.error(f"Rapid navigation test error: {e}")
async def _test_empty_form_submission(self, form: Locator, page: Page):
"""Test form submission with empty fields."""
try:
# Find all input fields
inputs = await form.query_selector_all('input, textarea, select')
if inputs:
# Try to submit empty form
submit_button = await form.query_selector('button[type="submit"], input[type="submit"]')
if submit_button:
await submit_button.click()
await page.wait_for_timeout(1000)
# Check if validation is working
error_elements = await page.query_selector_all('.error, .invalid, [class*="error"], [class*="invalid"]')
if not error_elements:
self._add_bug_report(
title="Missing Form Validation",
severity=BugSeverity.HIGH,
description="Form accepts empty submissions without validation",
steps_to_reproduce=["Leave form fields empty", "Submit form"],
expected_behavior="Form should show validation errors",
actual_behavior="Form submitted without validation",
url=page.url,
element_info={"form_action": await form.get_attribute("action")},
recommendations=["Add client-side validation", "Add server-side validation"]
)
except Exception as e:
logger.error(f"Empty form submission test error: {e}")
async def _test_sql_injection_forms(self, form: Locator, page: Page):
"""Test forms for SQL injection vulnerabilities."""
try:
inputs = await form.query_selector_all('input[type="text"], input[type="email"], textarea')
sql_payloads = [
"' OR '1'='1",
"'; DROP TABLE users; --",
"' UNION SELECT * FROM users --",
"admin'--",
"' OR 1=1#"
]
for input_field in inputs:
for payload in sql_payloads:
try:
await input_field.fill(payload)
submit_button = await form.query_selector('button[type="submit"], input[type="submit"]')
if submit_button:
await submit_button.click()
await page.wait_for_timeout(1000)
# Check for SQL error messages
content = await page.content()
sql_errors = [
"mysql_fetch_array", "ORA-01756", "Microsoft OLE DB Provider",
"SQLServer JDBC Driver", "PostgreSQL query failed", "Warning: mysql_",
"valid MySQL result", "MySqlClient.", "SQL syntax"
]
for error in sql_errors:
if error.lower() in content.lower():
self._add_bug_report(
title="SQL Injection Vulnerability",
severity=BugSeverity.CRITICAL,
description=f"SQL injection vulnerability detected with payload: {payload}",
steps_to_reproduce=[f"Enter payload: {payload}", "Submit form"],
expected_behavior="Input should be sanitized",
actual_behavior="SQL injection successful",
url=page.url,
element_info={"payload": payload, "error": error},
recommendations=["Use parameterized queries", "Sanitize input", "Implement proper validation"]
)
break
# Clear input for next test
await input_field.fill("")
except Exception as e:
logger.warning(f"SQL injection test error: {e}")
continue
except Exception as e:
logger.error(f"SQL injection form test error: {e}")
async def _test_xss_forms(self, form: Locator, page: Page):
"""Test forms for XSS vulnerabilities."""
try:
inputs = await form.query_selector_all('input[type="text"], input[type="email"], textarea')
xss_payloads = [
"",
"
",
"javascript:alert('XSS')",
"