How to Handle Mobile Responsive Testing with Selenium WebDriver
Mobile responsive testing is crucial for modern web applications as mobile traffic continues to dominate internet usage. Selenium WebDriver provides several powerful methods to test how your web applications behave across different mobile devices and screen sizes. This comprehensive guide covers everything you need to know about mobile responsive testing with Selenium WebDriver.
Understanding Mobile Responsive Testing
Mobile responsive testing involves verifying that your web application displays correctly and functions properly across various mobile devices, screen sizes, and orientations. Unlike traditional desktop testing, mobile responsive testing requires careful consideration of viewport dimensions, touch interactions, and mobile-specific browser behaviors.
Setting Up Mobile Device Emulation
Chrome Mobile Emulation
The most common approach for mobile responsive testing is using Chrome's mobile device emulation feature. This allows you to simulate various mobile devices without requiring physical devices.
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
def setup_mobile_chrome_driver(device_name="iPhone 12 Pro"):
chrome_options = Options()
# Enable mobile emulation
mobile_emulation = {"deviceName": device_name}
chrome_options.add_experimental_option("mobileEmulation", mobile_emulation)
# Additional mobile-specific options
chrome_options.add_argument("--disable-web-security")
chrome_options.add_argument("--disable-features=VizDisplayCompositor")
driver = webdriver.Chrome(options=chrome_options)
return driver
# Example usage
driver = setup_mobile_chrome_driver("iPhone 12 Pro")
driver.get("https://example.com")
Custom Viewport Dimensions
For more precise control, you can set custom viewport dimensions to test specific screen sizes:
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
def setup_custom_viewport(width, height):
chrome_options = Options()
# Set custom mobile viewport
mobile_emulation = {
"deviceMetrics": {
"width": width,
"height": height,
"pixelRatio": 3.0
},
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0 Mobile/15E148 Safari/604.1"
}
chrome_options.add_experimental_option("mobileEmulation", mobile_emulation)
driver = webdriver.Chrome(options=chrome_options)
return driver
# Test different screen sizes
driver = setup_custom_viewport(375, 812) # iPhone X dimensions
driver.get("https://example.com")
Firefox Mobile Testing
Firefox also supports mobile emulation through responsive design mode:
from selenium import webdriver
from selenium.webdriver.firefox.options import Options
def setup_mobile_firefox(width=375, height=812):
firefox_options = Options()
# Set mobile user agent
profile = webdriver.FirefoxProfile()
profile.set_preference("general.useragent.override",
"Mozilla/5.0 (iPhone; CPU iPhone OS 14_6 like Mac OS X) AppleWebKit/605.1.15")
driver = webdriver.Firefox(firefox_profile=profile, options=firefox_options)
# Set window size for mobile testing
driver.set_window_size(width, height)
return driver
driver = setup_mobile_firefox()
driver.get("https://example.com")
JavaScript Implementation
For JavaScript-based testing with Selenium WebDriver, you can use similar approaches:
const { Builder, By, Key, until } = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
async function setupMobileChrome(deviceName = 'iPhone 12 Pro') {
const options = new chrome.Options();
// Enable mobile emulation
options.setMobileEmulation({
deviceName: deviceName
});
// Additional mobile-specific options
options.addArguments('--disable-web-security');
options.addArguments('--disable-features=VizDisplayCompositor');
const driver = await new Builder()
.forBrowser('chrome')
.setChromeOptions(options)
.build();
return driver;
}
// Custom viewport setup
async function setupCustomViewport(width, height) {
const options = new chrome.Options();
options.setMobileEmulation({
deviceMetrics: {
width: width,
height: height,
pixelRatio: 3.0
},
userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_6 like Mac OS X) AppleWebKit/605.1.15'
});
const driver = await new Builder()
.forBrowser('chrome')
.setChromeOptions(options)
.build();
return driver;
}
// Example usage
(async function() {
const driver = await setupMobileChrome('iPhone 12 Pro');
await driver.get('https://example.com');
// Your test code here
await driver.quit();
})();
Advanced Mobile Testing Techniques
Testing Multiple Device Orientations
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
def test_device_orientations():
devices = [
{"name": "iPhone 12 Pro", "width": 390, "height": 844},
{"name": "iPhone 12 Pro Landscape", "width": 844, "height": 390},
{"name": "iPad", "width": 768, "height": 1024},
{"name": "iPad Landscape", "width": 1024, "height": 768}
]
for device in devices:
chrome_options = Options()
mobile_emulation = {
"deviceMetrics": {
"width": device["width"],
"height": device["height"],
"pixelRatio": 2.0
},
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_6 like Mac OS X) AppleWebKit/605.1.15"
}
chrome_options.add_experimental_option("mobileEmulation", mobile_emulation)
driver = webdriver.Chrome(options=chrome_options)
driver.get("https://example.com")
# Perform your tests here
print(f"Testing on {device['name']}: {device['width']}x{device['height']}")
driver.quit()
test_device_orientations()
Touch Interactions and Gestures
Mobile testing often requires simulating touch interactions:
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.touch_actions import TouchActions
def test_touch_interactions():
driver = setup_mobile_chrome_driver("iPhone 12 Pro")
driver.get("https://example.com")
# Find an element to interact with
element = driver.find_element(By.ID, "mobile-menu")
# Perform touch actions
touch_actions = TouchActions(driver)
touch_actions.tap(element).perform()
# Scroll simulation
driver.execute_script("window.scrollTo(0, 500);")
# Swipe simulation
driver.execute_script("""
var element = arguments[0];
var event = new TouchEvent('touchstart', {
touches: [new Touch({
identifier: 1,
target: element,
clientX: 100,
clientY: 100
})]
});
element.dispatchEvent(event);
""", element)
driver.quit()
test_touch_interactions()
Responsive Element Testing
Checking Element Visibility and Layout
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
def test_responsive_elements():
driver = setup_mobile_chrome_driver("iPhone 12 Pro")
driver.get("https://example.com")
# Wait for elements to load
wait = WebDriverWait(driver, 10)
# Check if mobile navigation is visible
mobile_nav = wait.until(EC.presence_of_element_located((By.CLASS_NAME, "mobile-nav")))
assert mobile_nav.is_displayed(), "Mobile navigation should be visible"
# Check if desktop navigation is hidden
desktop_nav = driver.find_elements(By.CLASS_NAME, "desktop-nav")
if desktop_nav:
assert not desktop_nav[0].is_displayed(), "Desktop navigation should be hidden on mobile"
# Verify element dimensions
element = driver.find_element(By.CLASS_NAME, "responsive-container")
size = element.size
location = element.location
print(f"Element size: {size['width']}x{size['height']}")
print(f"Element location: {location['x']}, {location['y']}")
# Check CSS properties
display_property = element.value_of_css_property("display")
width_property = element.value_of_css_property("width")
print(f"Display: {display_property}, Width: {width_property}")
driver.quit()
test_responsive_elements()
Testing Breakpoints
def test_responsive_breakpoints():
breakpoints = [
{"name": "Mobile", "width": 320, "height": 568},
{"name": "Mobile Large", "width": 414, "height": 896},
{"name": "Tablet", "width": 768, "height": 1024},
{"name": "Desktop", "width": 1920, "height": 1080}
]
for breakpoint in breakpoints:
driver = setup_custom_viewport(breakpoint["width"], breakpoint["height"])
driver.get("https://example.com")
# Test specific elements at each breakpoint
sidebar = driver.find_elements(By.CLASS_NAME, "sidebar")
if breakpoint["width"] < 768:
# Mobile: sidebar should be hidden or collapsed
if sidebar:
assert not sidebar[0].is_displayed() or "collapsed" in sidebar[0].get_attribute("class")
else:
# Desktop/Tablet: sidebar should be visible
if sidebar:
assert sidebar[0].is_displayed()
print(f"Breakpoint {breakpoint['name']} ({breakpoint['width']}px): Test passed")
driver.quit()
test_responsive_breakpoints()
Performance Testing on Mobile
Mobile responsive testing should also include performance considerations:
import time
from selenium import webdriver
def test_mobile_performance():
driver = setup_mobile_chrome_driver("iPhone 12 Pro")
# Enable performance logging
caps = driver.desired_capabilities
caps['goog:loggingPrefs'] = {'performance': 'ALL'}
start_time = time.time()
driver.get("https://example.com")
# Wait for page to fully load
WebDriverWait(driver, 10).until(
lambda d: d.execute_script("return document.readyState") == "complete"
)
load_time = time.time() - start_time
print(f"Page load time: {load_time:.2f} seconds")
# Check for performance metrics
performance_logs = driver.get_log('performance')
for log in performance_logs:
if 'Network.responseReceived' in log['message']:
print(f"Network response: {log['message']}")
driver.quit()
test_mobile_performance()
Best Practices for Mobile Responsive Testing
1. Test Popular Device Configurations
Focus on the most commonly used mobile devices and screen sizes:
POPULAR_DEVICES = [
{"name": "iPhone 12 Pro", "width": 390, "height": 844},
{"name": "iPhone SE", "width": 375, "height": 667},
{"name": "Samsung Galaxy S21", "width": 384, "height": 854},
{"name": "iPad", "width": 768, "height": 1024},
{"name": "iPad Pro", "width": 1024, "height": 1366}
]
def run_cross_device_tests():
for device in POPULAR_DEVICES:
driver = setup_custom_viewport(device["width"], device["height"])
driver.get("https://example.com")
# Run your test suite
perform_responsive_tests(driver, device["name"])
driver.quit()
def perform_responsive_tests(driver, device_name):
# Test navigation
# Test form interactions
# Test media queries
# Test touch interactions
pass
2. Implement Comprehensive Test Suites
class MobileResponsiveTestSuite:
def __init__(self, base_url):
self.base_url = base_url
def test_navigation_responsiveness(self, driver):
driver.get(self.base_url)
# Test hamburger menu
hamburger = driver.find_element(By.CLASS_NAME, "hamburger-menu")
hamburger.click()
# Verify mobile menu appears
mobile_menu = WebDriverWait(driver, 5).until(
EC.visibility_of_element_located((By.CLASS_NAME, "mobile-menu"))
)
assert mobile_menu.is_displayed()
def test_form_responsiveness(self, driver):
driver.get(f"{self.base_url}/contact")
# Test form field sizing
form_fields = driver.find_elements(By.TAG_NAME, "input")
for field in form_fields:
width = field.size['width']
viewport_width = driver.execute_script("return window.innerWidth")
# Form fields should not exceed viewport width
assert width <= viewport_width, f"Form field too wide: {width}px > {viewport_width}px"
def test_content_readability(self, driver):
driver.get(self.base_url)
# Check font sizes
headings = driver.find_elements(By.TAG_NAME, "h1")
for heading in headings:
font_size = heading.value_of_css_property("font-size")
font_size_px = int(font_size.replace("px", ""))
# Ensure readable font sizes on mobile
assert font_size_px >= 16, f"Heading font too small: {font_size_px}px"
3. Handle Mobile-Specific Challenges
When testing mobile responsive designs, consider implementing robust waiting strategies for dynamic content and proper error handling techniques to ensure your tests are reliable across different mobile environments.
Conclusion
Mobile responsive testing with Selenium WebDriver is essential for ensuring your web applications provide excellent user experiences across all devices. By implementing device emulation, testing various screen sizes and orientations, and following best practices for mobile testing, you can create comprehensive test suites that verify your application's responsiveness and functionality.
Remember to regularly update your device configurations to match current market trends and always test on actual devices when possible to complement your automated testing efforts. The techniques covered in this guide will help you build robust mobile responsive tests that catch issues before they reach your users.
For more advanced testing scenarios, consider combining these techniques with performance monitoring, accessibility testing, and cross-browser compatibility testing to ensure comprehensive coverage of your mobile responsive implementation.