""" 🤖 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')", "", "" ] for input_field in inputs: for payload in xss_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 if payload is reflected content = await page.content() if payload in content: self._add_bug_report( title="XSS Vulnerability", severity=BugSeverity.CRITICAL, description=f"XSS vulnerability detected with payload: {payload}", steps_to_reproduce=[f"Enter payload: {payload}", "Submit form"], expected_behavior="Input should be sanitized", actual_behavior="XSS payload reflected", url=page.url, element_info={"payload": payload}, recommendations=["Sanitize output", "Use CSP headers", "Validate input"] ) # Clear input for next test await input_field.fill("") except Exception as e: logger.warning(f"XSS test error: {e}") continue except Exception as e: logger.error(f"XSS form test error: {e}") async def _test_responsive_design(self, page: Page): """Test responsive design.""" try: viewports = [ {"width": 320, "height": 568}, # iPhone SE {"width": 375, "height": 667}, # iPhone 8 {"width": 768, "height": 1024}, # iPad {"width": 1024, "height": 768}, # Desktop {"width": 1920, "height": 1080} # Large desktop ] for viewport in viewports: await page.set_viewport_size(viewport) await page.wait_for_timeout(500) # Check for layout issues elements = await page.query_selector_all('*') for element in elements: try: box = await element.bounding_box() if box and (box['width'] > viewport['width'] or box['height'] > viewport['height']): self._add_bug_report( title="Responsive Design Issue", severity=BugSeverity.MEDIUM, description=f"Element overflows viewport at {viewport['width']}x{viewport['height']}", steps_to_reproduce=[f"Set viewport to {viewport['width']}x{viewport['height']}", "Check layout"], expected_behavior="Elements should fit within viewport", actual_behavior="Element overflows viewport", url=page.url, element_info={"viewport": viewport, "element_box": box}, recommendations=["Fix CSS media queries", "Adjust element sizing", "Test responsive design"] ) except Exception as e: continue except Exception as e: logger.error(f"Responsive design test error: {e}") async def _test_page_load_time(self, page: Page): """Test page load time.""" try: start_time = await page.evaluate("performance.now()") await page.reload() await page.wait_for_load_state('networkidle') end_time = await page.evaluate("performance.now()") load_time = (end_time - start_time) / 1000 # Convert to seconds if load_time > self.performance_thresholds['page_load_time']: self._add_bug_report( title="Slow Page Load Time", severity=BugSeverity.MEDIUM, description=f"Page load time is {load_time:.2f}s, exceeds threshold of {self.performance_thresholds['page_load_time']}s", steps_to_reproduce=["Reload page", "Measure load time"], expected_behavior="Page should load quickly", actual_behavior=f"Page loads in {load_time:.2f}s", url=page.url, element_info={"load_time": load_time, "threshold": self.performance_thresholds['page_load_time']}, recommendations=["Optimize images", "Minify CSS/JS", "Use CDN", "Enable compression"] ) except Exception as e: logger.error(f"Page load time test error: {e}") async def _check_for_errors(self, page: Page) -> bool: """Check for JavaScript errors on the page.""" try: # Check console for errors errors = await page.evaluate(""" () => { if (window.fagunErrorMonitor) { return window.fagunErrorMonitor.getErrors(); } return []; } """) return len(errors) > 0 except Exception: return False def _add_bug_report(self, 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]): """Add a bug report.""" bug = BugReport( title=title, severity=severity, description=description, steps_to_reproduce=steps_to_reproduce, expected_behavior=expected_behavior, actual_behavior=actual_behavior, url=url, element_info=element_info, recommendations=recommendations ) self.bugs_found.append(bug) logger.info(f"🐛 Bug found: {title} ({severity.value})") # Placeholder methods for other tests async def _back_forward_test(self, page: Page): """Test browser back/forward functionality.""" pass async def _refresh_test(self, page: Page): """Test page refresh functionality.""" pass async def _url_manipulation_test(self, page: Page): """Test URL manipulation.""" pass async def _test_invalid_form_data(self, form: Locator, page: Page): """Test form with invalid data.""" pass async def _test_large_form_data(self, form: Locator, page: Page): """Test form with large data.""" pass async def _test_special_characters(self, form: Locator, page: Page): """Test form with special characters.""" pass async def _test_accessibility(self, page: Page): """Test accessibility features.""" pass async def _test_hover_effects(self, page: Page): """Test hover effects.""" pass async def _test_clickable_areas(self, page: Page): """Test clickable areas.""" pass async def _test_scrolling_behavior(self, page: Page): """Test scrolling behavior.""" pass async def _test_resource_loading(self, page: Page): """Test resource loading performance.""" pass async def _test_memory_usage(self, page: Page): """Test memory usage.""" pass async def _test_network_performance(self, page: Page): """Test network performance.""" pass async def _test_csrf_vulnerabilities(self, page: Page): """Test CSRF vulnerabilities.""" pass async def _test_clickjacking(self, page: Page): """Test clickjacking vulnerabilities.""" pass async def _test_session_management(self, page: Page): """Test session management.""" pass async def _test_authentication(self, page: Page): """Test authentication.""" pass # Global enhanced testing engine enhanced_ai_testing_engine = EnhancedAITestingEngine()