Thursday, 2 January, 2025
HomeProgrammingPythonMastering Selenium Python: From Beginner to Advanced Automation Expert – Lesson 7:...

Mastering Selenium Python: From Beginner to Advanced Automation Expert – Lesson 7: Advanced Browser Controls

In this lesson, we’ll explore advanced browser control features in Selenium 4, including managing multiple windows and tabs, handling iframes, executing JavaScript, managing cookies, and configuring browser capabilities. These skills are essential for creating sophisticated test automation solutions.

Managing Multiple Windows and Tabs

Selenium 4 provides enhanced capabilities for handling multiple windows and tabs efficiently:

from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

class WindowManager:
    def __init__(self, driver):
        self.driver = driver
        self.main_window = driver.current_window_handle
        
    def switch_to_new_window(self, timeout=10):
        """Switch to newly opened window"""
        def wait_for_new_window(driver):
            handles = driver.window_handles
            return len(handles) > 1
            
        WebDriverWait(self.driver, timeout).until(wait_for_new_window)
        
        for handle in self.driver.window_handles:
            if handle != self.main_window:
                self.driver.switch_to.window(handle)
                return True
        return False
        
    def create_new_tab(self, url=None):
        """Create and switch to new tab"""
        self.driver.execute_script("window.open('');")
        self.switch_to_new_window()
        if url:
            self.driver.get(url)
            
    def close_current_tab(self):
        """Close current tab and switch back to main window"""
        if len(self.driver.window_handles) > 1:
            self.driver.close()
            self.driver.switch_to.window(self.main_window)
            
    def get_all_window_titles(self):
        """Get titles of all open windows"""
        titles = {}
        current = self.driver.current_window_handle
        
        for handle in self.driver.window_handles:
            self.driver.switch_to.window(handle)
            titles[handle] = self.driver.title
            
        self.driver.switch_to.window(current)
        return titles

# Usage example
window_manager = WindowManager(driver)
window_manager.create_new_tab("https://example.com")

Working with iFrames

Modern web applications often use iframes for embedding content. Here’s how to handle them effectively:

class IFrameHandler:
    def __init__(self, driver):
        self.driver = driver
        
    def switch_to_iframe(self, identifier, by=By.CSS_SELECTOR):
        """Switch to iframe using various locator strategies"""
        try:
            iframe = WebDriverWait(self.driver, 10).until(
                EC.presence_of_element_located((by, identifier))
            )
            self.driver.switch_to.frame(iframe)
            return True
        except Exception as e:
            print(f"Failed to switch to iframe: {str(e)}")
            return False
            
    def switch_to_parent_frame(self):
        """Switch back to parent frame"""
        self.driver.switch_to.parent_frame()
        
    def switch_to_default_content(self):
        """Switch back to default content"""
        self.driver.switch_to.default_content()
        
    def get_iframe_content(self, identifier, by=By.CSS_SELECTOR):
        """Get content from iframe safely"""
        if self.switch_to_iframe(identifier, by):
            content = self.driver.page_source
            self.switch_to_default_content()
            return content
        return None

# Usage example
iframe_handler = IFrameHandler(driver)
iframe_handler.switch_to_iframe("iframe-name", By.NAME)

JavaScript Execution

Selenium 4 provides powerful JavaScript execution capabilities:

class JavaScriptExecutor:
    def __init__(self, driver):
        self.driver = driver
        
    def execute_script(self, script, *args):
        """Execute JavaScript code"""
        return self.driver.execute_script(script, *args)
        
    def scroll_into_view(self, element):
        """Scroll element into view"""
        self.execute_script(
            "arguments[0].scrollIntoView({behavior: 'smooth', block: 'center'});",
            element
        )
        
    def highlight_element(self, element, duration=2):
        """Highlight element temporarily for debugging"""
        original_style = element.get_attribute('style')
        self.execute_script("""
            arguments[0].style.border = '3px solid red';
            arguments[0].style.backgroundColor = 'yellow';
            setTimeout(() => {
                arguments[0].style = arguments[1];
            }, arguments[2] * 1000);
        """, element, original_style, duration)
        
    def get_page_load_metrics(self):
        """Get page performance metrics"""
        return self.execute_script("""
            let performance = window.performance;
            let timing = performance.timing;
            return {
                'pageLoadTime': timing.loadEventEnd - timing.navigationStart,
                'domContentLoaded': timing.domContentLoadedEventEnd - timing.navigationStart,
                'firstPaint': performance.getEntriesByType('paint')[0].startTime,
                'firstContentfulPaint': performance.getEntriesByType('paint')[1].startTime
            };
        """)

# Usage example
js_executor = JavaScriptExecutor(driver)
metrics = js_executor.get_page_load_metrics()

Managing Cookies and Storage

Handling browser cookies and local storage effectively:

class BrowserStorage:
    def __init__(self, driver):
        self.driver = driver
        
    def get_all_cookies(self):
        """Get all browser cookies"""
        return self.driver.get_cookies()
        
    def add_cookie(self, cookie_dict):
        """Add a new cookie"""
        self.driver.add_cookie(cookie_dict)
        
    def delete_cookie(self, cookie_name):
        """Delete specific cookie"""
        self.driver.delete_cookie(cookie_name)
        
    def clear_cookies(self):
        """Clear all cookies"""
        self.driver.delete_all_cookies()
        
    def get_local_storage_item(self, key):
        """Get item from local storage"""
        return self.driver.execute_script(
            f"return window.localStorage.getItem('{key}');"
        )
        
    def set_local_storage_item(self, key, value):
        """Set item in local storage"""
        self.driver.execute_script(
            f"window.localStorage.setItem('{key}', '{value}');"
        )
        
    def clear_local_storage(self):
        """Clear local storage"""
        self.driver.execute_script("window.localStorage.clear();")
        
    def get_session_storage_item(self, key):
        """Get item from session storage"""
        return self.driver.execute_script(
            f"return window.sessionStorage.getItem('{key}');"
        )

# Usage example
storage = BrowserStorage(driver)
storage.set_local_storage_item("user_preferences", '{"theme":"dark"}')

Configuring Browser Capabilities

Customize browser behavior with advanced capabilities:

from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service

class BrowserConfiguration:
    @staticmethod
    def get_chrome_options(
        headless=False,
        disable_gpu=False,
        window_size=(1920, 1080),
        download_dir=None,
        proxy=None
    ):
        """Configure Chrome options"""
        options = Options()
        
        if headless:
            options.add_argument('--headless')
            
        if disable_gpu:
            options.add_argument('--disable-gpu')
            
        options.add_argument(f'--window-size={window_size[0]},{window_size[1]}')
        
        if download_dir:
            prefs = {
                'download.default_directory': download_dir,
                'download.prompt_for_download': False
            }
            options.add_experimental_option('prefs', prefs)
            
        if proxy:
            options.add_argument(f'--proxy-server={proxy}')
            
        # Additional useful options
        options.add_argument('--no-sandbox')
        options.add_argument('--disable-dev-shm-usage')
        options.add_argument('--disable-blink-features=AutomationControlled')
        
        return options
        
    @staticmethod
    def create_chrome_driver(options=None, service_args=None):
        """Create Chrome driver with specified options"""
        service = Service()
        if service_args:
            for arg in service_args:
                service.add_argument(arg)
                
        if not options:
            options = Options()
            
        return webdriver.Chrome(service=service, options=options)

# Usage example
config = BrowserConfiguration()
options = config.get_chrome_options(
    headless=True,
    window_size=(1920, 1080),
    download_dir="/downloads"
)
driver = config.create_chrome_driver(options=options)

Performance Monitoring

Monitor browser and page performance:

class PerformanceMonitor:
    def __init__(self, driver):
        self.driver = driver
        
    def get_network_metrics(self):
        """Get network performance metrics"""
        return self.driver.execute_script("""
            let performance = window.performance;
            let timing = performance.timing;
            return {
                'dnsLookup': timing.domainLookupEnd - timing.domainLookupStart,
                'tcpConnection': timing.connectEnd - timing.connectStart,
                'serverResponse': timing.responseStart - timing.requestStart,
                'pageDownload': timing.responseEnd - timing.responseStart,
                'domProcessing': timing.domComplete - timing.domLoading
            };
        """)
        
    def get_memory_usage(self):
        """Get browser memory usage"""
        return self.driver.execute_script("""
            return {
                'jsHeapSizeLimit': performance.memory.jsHeapSizeLimit,
                'totalJSHeapSize': performance.memory.totalJSHeapSize,
                'usedJSHeapSize': performance.memory.usedJSHeapSize
            };
        """)

# Usage example
monitor = PerformanceMonitor(driver)
network_metrics = monitor.get_network_metrics()

Conclusion

This lesson has covered advanced browser control features in Selenium 4, providing you with the tools to handle complex automation scenarios. These techniques will help you create more sophisticated and reliable test automation solutions. The next lesson will focus on building a complete test automation framework using these advanced features.

Practice Exercises:

  1. Create a script that handles multiple browser windows and performs actions in each
  2. Implement a framework for managing iframes in a complex web application
  3. Build a performance monitoring solution for your test automation
  4. Create a cookie and local storage management system for your tests
Series Navigation<< Mastering Selenium Python: From Beginner to Advanced Automation Expert – Lesson 6: Handling Dynamic Elements and WaitsMastering Selenium Python: From Beginner to Advanced Automation Expert – Lesson 8: Test Automation Framework Design >>
Related articles

Most Popular