Headless mode for CI in Selenium Python - Build an Automation Script
from selenium import webdriver from selenium.webdriver.chrome.options import Options 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_login_headless(): options = Options() options.headless = True driver = webdriver.Chrome(options=options) wait = WebDriverWait(driver, 10) try: driver.get('https://example.com/login') username_input = wait.until(EC.presence_of_element_located((By.ID, 'username'))) username_input.send_keys('testuser') password_input = driver.find_element(By.ID, 'password') password_input.send_keys('Test@1234') login_button = driver.find_element(By.ID, 'loginBtn') login_button.click() wait.until(EC.url_to_be('https://example.com/dashboard')) welcome_message = wait.until(EC.presence_of_element_located((By.ID, 'welcomeMessage'))) assert welcome_message.text == 'Welcome, testuser!' finally: driver.quit() if __name__ == '__main__': test_login_headless()
This script uses Selenium WebDriver with Chrome in headless mode to simulate a browser without opening a window, ideal for CI environments.
We set options.headless = True to enable headless mode.
Explicit waits ensure the script waits for elements to appear or URL to change before interacting or asserting, avoiding flaky tests.
We locate elements by their id attributes, which is a best practice for stable selectors.
The test inputs the username and password, clicks login, waits for the dashboard URL, then verifies the welcome message text.
Finally, the browser is closed with driver.quit() to free resources.
Now add data-driven testing with 3 different username and password combinations to verify login success or failure.
Practice
headless mode on a Continuous Integration (CI) server?Solution
Step 1: Understand headless mode purpose
Headless mode runs the browser without opening a visible window, saving system resources.Step 2: Relate to CI environment needs
CI servers often run tests automatically without user interaction, so headless mode speeds up tests and reduces resource use.Final Answer:
Tests run faster and use fewer resources because no browser window is displayed -> Option CQuick Check:
Headless mode = faster, resource-saving tests [OK]
- Thinking headless mode requires manual input
- Believing headless mode only works on Windows
- Assuming headless mode automatically creates screenshots
Solution
Step 1: Recall correct syntax for headless Chrome
In Selenium Python, headless mode is enabled by adding the argument '--headless' to ChromeOptions.Step 2: Check each option for correctness
options = webdriver.ChromeOptions() options.add_argument('--headless') browser = webdriver.Chrome(options=options) correctly uses options.add_argument('--headless') and passes options to Chrome driver.Final Answer:
options = webdriver.ChromeOptions() options.add_argument('--headless') browser = webdriver.Chrome(options=options) -> Option BQuick Check:
Use add_argument('--headless') to enable headless mode [OK]
- Setting options.headless = True (not supported)
- Trying to set headless directly on browser instance
- Using non-existent set_headless method
from selenium import webdriver
options = webdriver.FirefoxOptions()
options.add_argument('--headless')
driver = webdriver.Firefox(options=options)
driver.get('https://example.com')
title = driver.title
driver.quit()
print(title)Solution
Step 1: Understand Firefox headless support
Firefox supports headless mode via options.add_argument('--headless'), so the browser runs without UI.Step 2: Analyze code behavior
The code loads 'https://example.com', gets the page title 'Example Domain', then quits the driver and prints the title.Final Answer:
Prints the page title 'Example Domain' without opening a browser window -> Option AQuick Check:
Headless Firefox loads page and returns title correctly [OK]
- Assuming headless disables page loading
- Thinking Firefox lacks headless support
- Expecting visible browser window in headless mode
options = webdriver.ChromeOptions()
options.add_argument('--headless')
driver = webdriver.Chrome(options=options)
driver.get('https://example.com')
What is the most likely cause and fix?Solution
Step 1: Identify common CI environment issue
On many CI servers, Chrome needs '--no-sandbox' to run properly in headless mode to avoid permission issues.Step 2: Apply fix to options
Add options.add_argument('--no-sandbox') along with '--headless' to fix timeout errors.Final Answer:
Missing '--no-sandbox' argument; add options.add_argument('--no-sandbox') for CI environments -> Option DQuick Check:
Use '--no-sandbox' with headless Chrome on CI [OK]
- Removing headless argument thinking it's unsupported
- Calling maximize_window() unnecessarily in headless
- Changing URL without reason
Solution
Step 1: Understand headless mode limitations
Headless mode can cause layout differences; setting window size helps elements render correctly.Step 2: Use modern headless flag and disable GPU
Using '--headless=new' enables the latest headless mode in Chrome, and '--disable-gpu' avoids GPU issues in CI.Step 3: Combine all options for stable tests
Adding '--window-size=1920,1080' ensures consistent viewport, preventing element interaction failures.Final Answer:
Enable headless mode with '--headless=new', add '--disable-gpu', and set a window size with options.add_argument('--window-size=1920,1080') -> Option AQuick Check:
Use new headless, disable GPU, and set window size for stable CI tests [OK]
- Ignoring window size causing element not interactable errors
- Using old headless mode without '--headless=new'
- Disabling headless mode defeats CI automation purpose
Ready to prove it?
Pass the test and this pattern moves unknown
