I’m working on automating a login process for our company’s HR system using Selenium with headless Chrome. The script runs perfectly when I use the regular browser mode, but as soon as I switch to headless mode, it fails during the login process.
Here’s my current setup:
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
chrome_options = Options()
chrome_options.add_argument("--headless")
chrome_options.add_argument('--no-sandbox')
chrome_options.add_argument('--start-maximized')
chrome_options.add_argument('--disable-infobars')
chrome_options.add_argument("--disable-extensions")
driver = webdriver.Chrome(options=chrome_options)
print("Starting headless automation")
# Open the target site
driver.get('https://example-hr-portal.com')
print('Accessing HR portal')
# Perform login
print('Entering login details')
username = '[email protected]'
password = 'mypassword123'
driver.find_element_by_id('usernameField').send_keys(username)
driver.find_element_by_id('passwordField').send_keys(password)
driver.find_element_by_id('loginButton').click()
print('Attempting login')
# Wait for dashboard to load
try:
WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CLASS_NAME, 'dashboard-icon')))
finally:
driver.find_element_by_class_name('dashboard-icon').click()
The error I’m getting is:
selenium.common.exceptions.ElementNotInteractableException: Message: element not interactable
(Session info: headless chrome=79.0.3945.130)
I’m confused because the same code works fine in regular browser mode. What could be causing this issue in headless mode?
had same problem with our crm system last month. try adding --disable-blink-features=AutomationControlled to hide the fact that its selenium driving the browser. some sites block headless automation. also your using deprecated methods - switch to driver.find_element(By.ID, 'usernameField') syntax. one more thing that worked for me was adding time.sleep(2) after page loads, sometimes headless mode is too fast and elements arent fully rendered yet even if they appear present.
I ran into this exact issue a few months back with our internal application. The problem is usually related to viewport size differences between headless and regular mode. Even though you have --start-maximized, headless Chrome often defaults to a smaller viewport which can cause elements to be positioned differently or hidden behind overlays.
Try adding explicit window size arguments like --window-size=1920,1080 to your chrome options. Also, I noticed you’re clicking the dashboard icon in the finally block which will execute regardless of whether the wait succeeds or fails. Move that click outside the try-finally block and add proper error handling.
Another thing that helped me was adding a small delay after the login click before waiting for the dashboard element, since some sites have loading animations that can interfere with element detection in headless mode.
This behavior often stems from JavaScript-heavy sites that render elements differently in headless environments. I encountered similar issues when automating our payroll system last year. The site was using conditional loading based on browser detection, and headless Chrome triggered different code paths. First, try adding --disable-web-security and --disable-features=VizDisplayCompositor to your options. Some HR portals implement additional security checks that interfere with headless browsers. Second, replace those deprecated find_element_by_* methods with the newer find_element(By.ID, 'elementId') syntax since you’re already importing By. Most importantly, add explicit waits before each interaction. Don’t just wait for presence - use element_to_be_clickable instead. The login button might be present but covered by loading overlays or animations that complete faster in regular mode. I also recommend taking screenshots with driver.save_screenshot('debug.png') at key points to see what’s actually happening in headless mode.