selenium
python
deprecationwarning
executable_path
webdriver

DeprecationWarning executable_path has been deprecated selenium python

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

If Selenium prints a warning that executable_path has been deprecated, the fix is usually small but worth doing immediately. The old constructor style still appears in many code samples, yet newer Selenium versions expect driver startup details to be provided through a Service object. Updating now keeps test code compatible and makes WebDriver setup easier to manage centrally.

What the Warning Actually Means

Older Selenium code often passed the driver binary path directly into the browser constructor. That style mixed browser options, driver process startup, and path configuration into one call. The Service class separates those responsibilities so the driver process can be configured explicitly.

Old pattern:

python
1from selenium import webdriver
2
3# Deprecated style
4driver = webdriver.Chrome(executable_path="/usr/local/bin/chromedriver")

Current pattern:

python
1from selenium import webdriver
2from selenium.webdriver.chrome.service import Service
3
4service = Service("/usr/local/bin/chromedriver")
5driver = webdriver.Chrome(service=service)

The warning is not about navigation or element lookup. It is specifically about how the local driver process is started.

Migrate to a Driver Factory Instead of Fixing Tests One by One

The cleanest migration is usually a single helper that constructs browsers for the whole test suite. That gives one place to define options, headless behavior, logging flags, download directories, and local path configuration.

python
1import os
2from selenium import webdriver
3from selenium.webdriver.chrome.options import Options
4from selenium.webdriver.chrome.service import Service
5
6
7def make_driver(headless: bool = True) -> webdriver.Chrome:
8    options = Options()
9    if headless:
10        options.add_argument("--headless=new")
11    options.add_argument("--window-size=1440,900")
12
13    driver_path = os.environ["CHROMEDRIVER_PATH"]
14    service = Service(driver_path)
15    return webdriver.Chrome(service=service, options=options)
16
17
18with make_driver() as driver:
19    driver.get("https://example.com")
20    print(driver.title)

When the path, browser flags, or test infrastructure change, you update one module instead of chasing repeated constructor code across dozens of files.

Keep Version Compatibility Separate From API Migration

Many teams change the constructor syntax and then assume the problem is solved. In practice, a second class of failures shows up when the browser version and the driver version are out of sync. The deprecation fix handles the Selenium API shape. It does not fix Chrome and ChromeDriver incompatibility, missing browser packages in CI, or remote execution misconfiguration.

If you use dynamic driver installation in local development, keep it explicit:

python
1from selenium import webdriver
2from selenium.webdriver.chrome.service import Service
3from webdriver_manager.chrome import ChromeDriverManager
4
5service = Service(ChromeDriverManager().install())
6driver = webdriver.Chrome(service=service)
7
8driver.get("https://example.com")
9print(driver.current_url)
10driver.quit()

That is convenient on a laptop, but CI often benefits from pinned browser and driver versions so failures are reproducible.

Distinguish Local Drivers From Remote Browsers

The Service class is for local browser startup. If your suite runs against Selenium Grid or a cloud provider, the local driver path is irrelevant and you should create a remote session instead.

python
1from selenium import webdriver
2
3options = webdriver.ChromeOptions()
4options.add_argument("--window-size=1440,900")
5
6driver = webdriver.Remote(
7    command_executor="http://localhost:4444/wd/hub",
8    options=options,
9)
10
11driver.get("https://example.com")
12print(driver.title)
13driver.quit()

Separating these two paths avoids a messy helper that tries to support every execution mode through conditionals and environment-specific hacks.

Use the Migration as a Test Infrastructure Cleanup

Warnings like this are a good prompt to tighten the rest of the browser setup layer. Centralize timeouts, log browser versions during startup, and fail CI if deprecated code patterns return. That turns a one-line warning fix into a real infrastructure improvement.

Even a lightweight check helps:

bash
rg "executable_path=" tests/ src/

If that search returns nothing and all browser creation flows through a factory, future Selenium upgrades become much easier to reason about.

Common Pitfalls

The most common mistake is replacing executable_path in one file while leaving the old pattern in helpers or fixtures. Another is assuming the warning caused every startup failure when the real issue is a browser-driver version mismatch. Teams also run into trouble by mixing local Service startup with remote-grid code paths in the same function.

Summary

  • Replace deprecated executable_path usage with a Service object.
  • Move browser construction into one shared helper instead of patching tests ad hoc.
  • Treat API migration and browser-driver version compatibility as separate concerns.
  • Use Service only for local drivers; remote sessions should use webdriver.Remote.
  • Search the codebase for old constructor patterns so the warning does not come back.

Course illustration
Course illustration

All Rights Reserved.