Why non-functional quality affects user experience in Testing Fundamentals - Automation Benefits in Action
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 import time class LoginPage: def __init__(self, driver): self.driver = driver self.username_input = (By.ID, 'username') self.password_input = (By.ID, 'password') self.login_button = (By.ID, 'loginBtn') def login(self, username, password): self.driver.find_element(*self.username_input).clear() self.driver.find_element(*self.username_input).send_keys(username) self.driver.find_element(*self.password_input).clear() self.driver.find_element(*self.password_input).send_keys(password) self.driver.find_element(*self.login_button).click() class DashboardPage: def __init__(self, driver): self.driver = driver self.dashboard_header = (By.ID, 'dashboardHeader') def is_loaded(self): return WebDriverWait(self.driver, 10).until( EC.visibility_of_element_located(self.dashboard_header) ) class FormPage: def __init__(self, driver): self.driver = driver self.input_field = (By.ID, 'inputField') self.submit_button = (By.ID, 'submitBtn') self.error_message = (By.ID, 'errorMsg') def enter_invalid_data(self): self.driver.find_element(*self.input_field).clear() self.driver.find_element(*self.input_field).send_keys('invalid_data!') self.driver.find_element(*self.submit_button).click() def get_error_message(self): return WebDriverWait(self.driver, 5).until( EC.visibility_of_element_located(self.error_message) ).text def test_application_responsiveness_and_error_handling(): options = webdriver.ChromeOptions() # Enable network throttling via DevTools protocol driver = webdriver.Chrome(options=options) driver.get('https://example-app.com/login') login_page = LoginPage(driver) dashboard_page = DashboardPage(driver) form_page = FormPage(driver) # Normal network test start_time = time.time() login_page.login('testuser', 'password123') dashboard_page.is_loaded() load_time_normal = time.time() - start_time assert load_time_normal <= 3, f'Dashboard load time too high: {load_time_normal}s' # Simulate slow network (example using Chrome DevTools Protocol) driver.execute_cdp_cmd('Network.enable', {}) driver.execute_cdp_cmd('Network.emulateNetworkConditions', { 'offline': False, 'latency': 2000, # 2 seconds latency 'downloadThroughput': 500 * 1024 / 8, # 500 kbps 'uploadThroughput': 500 * 1024 / 8 }) driver.get('https://example-app.com/login') start_time = time.time() login_page.login('testuser', 'password123') dashboard_page.is_loaded() load_time_slow = time.time() - start_time assert load_time_slow <= 6, f'Dashboard load time too high under slow network: {load_time_slow}s' # Reset network conditions driver.execute_cdp_cmd('Network.disable', {}) # Test error handling driver.get('https://example-app.com/form') form_page.enter_invalid_data() error_text = form_page.get_error_message() assert 'invalid' in error_text.lower(), 'Error message not user-friendly or missing' # Check application responsiveness after error try: driver.find_element(*form_page.input_field).is_enabled() responsive = True except Exception: responsive = False assert responsive, 'Application not responsive after error' driver.quit()
This test script uses Selenium with Python to automate the manual test case steps.
We define Page Object classes for the login page, dashboard, and form page to keep locators and actions organized and reusable.
The test function opens the login page, performs login, and measures the time taken for the dashboard to load using explicit waits to ensure the page is ready.
It asserts that the load time is within acceptable limits under normal and simulated slow network conditions. Network throttling is done using Chrome DevTools Protocol commands.
Then it navigates to a form page, enters invalid data to trigger an error, and verifies the error message is displayed and user-friendly.
Finally, it checks that the application remains responsive after the error by verifying the input field is enabled.
Explicit waits avoid flaky tests, and assertions check both timing and content to ensure good user experience related to non-functional quality.
Now add data-driven testing with 3 different user credentials and invalid inputs to verify consistent behavior.