Chapter 02Lesson 01~105 minutes

Selenium Ecosystem, Installation, and First WebDriver Session: Core Concepts and Mental Model

Install Selenium with a mental model first: a project dependency, a language binding, a driver-management decision, a browser driver, a browser binary, and a WebDriver session are related, but they are not the same object or state.

EcosystemSelenium ManagerDriverBrowserSession lifecycle

Learning objectives

  • Explain how a Selenium project, language binding, Selenium Manager, browser driver, browser binary, and WebDriver session fit together.
  • Distinguish a project dependency from a system browser, a driver executable, and Selenium Server/Grid.
  • Explain what Selenium Manager does by default and when an explicit driver path changes that behavior.
  • Inspect binding, browser, driver, platform, capability, and session evidence without mutating a production target.
  • Describe the create → command → quit lifecycle and why teardown is part of correctness.
  • Connect environment provenance to reproducible local and CI browser automation.

1. Why installation folklore causes flaky automation

“Install Selenium” sounds like one action, but browser automation crosses several independently versioned layers. Your Python project contains the Selenium binding. The operating system provides—or Selenium Manager may manage—a browser. A browser-specific driver implements the WebDriver remote end for that browser. The binding creates a session through that driver and sends commands. If a team treats all of those as one package called “Selenium,” failures become mysterious and machine-specific.

A reproducible setup records the identity of each layer. The useful question is not “Does Selenium work on my laptop?” It is “Which binding created which session against which browser and driver, under which options and environment, and did the session terminate cleanly?”

2. The ecosystem and first-session mental model

Project dependency to browser session

The following diagram visualizes the relationships described in The ecosystem and first-session mental model. Read the nodes in sequence and use the arrows to connect the conceptual state changes to the explanation around the diagram.

flowchart TD
  P["Python project"] --> B["selenium 4.47.0 binding"]
  B --> M["Selenium Manager when driver is unavailable"]
  M --> D["Browser driver / WebDriver remote end"]
  D --> R["Browser binary"]
  B --> S["WebDriver session"]
  S --> D
  R --> A["Loopback AUT"]
  S --> E["Capabilities + session evidence"]

The binding is the API your Python code imports. Selenium Manager is a Rust CLI shipped with Selenium and invoked by the binding when driver management is needed. The browser driver is the browser-specific WebDriver implementation. The browser binary is the actual Chrome, Firefox, Edge, Safari, or another supported browser. The WebDriver session is the negotiated runtime relationship that exists only after session creation succeeds.

Selenium Server/Grid is a different boundary: it is required for remote/distributed WebDriver execution, not for the simple local webdriver.Chrome() path used here.

3. Objects, state stores, and ownership

The following table organizes the key choices and evidence for Objects, state stores, and ownership. Use it together with the surrounding prose so the rows serve as a comparison aid rather than standalone rules.

Object/state Lives where Owned by What can go wrong
Project dependency virtual environment / dependency file project floating or incompatible binding version
Selenium Manager shipped with Selenium binding Selenium project network/proxy/cache/platform resolution failure
Driver executable PATH, explicit service path, or Manager cache browser vendor / resolver missing, stale, wrong architecture, browser mismatch
Browser binary/profile system installation or managed cache; runtime profile browser vendor / test runtime missing browser, policy restriction, shared mutable profile
WebDriver session driver/browser processes test lifecycle creation failure, wrong capabilities, leak after exception
AUT/test data application environment application/test setup dirty state mistaken for driver failure
Evidence test workspace test/reporting layer missing versions, private paths, credentials, or PII leaked

4. Selenium Manager: default automation, not magic

Current Selenium bindings use Selenium Manager by default when a required browser driver is unavailable. Its driver-management path discovers the installed browser version, resolves the corresponding driver version using browser-vendor metadata, downloads the driver when needed, and stores it in a local cache (by default ~/.cache/selenium). It can also manage supported browser binaries when needed.

That automation removes a large amount of manual setup, but it creates observable dependencies: first-run network access may be needed, corporate proxies can block resolution, cache state affects repeat runs, and a manually supplied driver path or usable driver on the machine can change which executable is selected. The correct production habit is to record the resulting capabilities and Manager/driver diagnostics when a session cannot start.

Privacy note: current Selenium Manager documentation states that anonymized usage statistics are enabled by default and can be disabled with SE_AVOID_STATS=true. Organizations with stricter telemetry policy should decide this explicitly rather than assuming no network metadata leaves the machine.

5. Session creation and quit are one correctness contract

webdriver.Chrome() is not merely a Python constructor. It initiates driver resolution, starts a local driver service, launches or connects to a browser, negotiates capabilities, and creates a session identifier. Every command after that is scoped to the live session. driver.quit() asks the remote end to close every browser window in that session and terminate the session. If your test raises an exception before teardown and you have no finally or framework fixture, you may leave browser/driver processes behind.

from selenium import __version__ as selenium_version
from selenium import webdriver

print(f"selenium={selenium_version}")

driver = None
try:
    driver = webdriver.Chrome()
    caps = driver.capabilities
    print(f"session_id={driver.session_id}")
    print(f"browser={caps.get('browserName')}")
    print(f"browser_version={caps.get('browserVersion')}")
    print(f"platform={caps.get('platformName')}")
    chrome = caps.get('chrome', {})
    print(f"chromedriver={chrome.get('chromedriverVersion', 'not-reported')}")
finally:
    if driver is not None:
        driver.quit()

This script performs a read-only environment inspection. It does not navigate to a public site. The returned values are more useful than guessing from package names because they describe the session Selenium actually created.

6. Selenium Server/Grid is not part of the local installation path

For a local session, the Python binding talks to a locally managed driver service. For a remote session, the binding talks to Selenium Server/Grid or another WebDriver-compatible remote endpoint. The remote service then decides where the browser session runs. Installing the selenium Python package does not automatically mean Grid is running, and downloading Selenium Server is not required to automate one local browser.

Chapter 19 introduces Grid architecture. Chapter 02 deliberately keeps the local boundary small so a first failure can be attributed to the binding/Manager/driver/browser/session chain instead of distributed infrastructure.

7. DevOps connection: environment provenance is release evidence

A green browser test is difficult to trust when nobody can reproduce the environment that produced it. Record the Selenium binding version, Python version, browser name/version, driver version when reported, platform, relevant options, target environment, and test-data identity. In CI, preserve that alongside the test result. This makes a later red build diagnosable as an application regression, environment drift, browser rollout, or automation defect instead of an undifferentiated failure.

Knowledge check

Is the Selenium Python package the browser driver?

When does Selenium Manager normally participate?

Why should a test record returned capabilities?

What is the local Selenium Server requirement for webdriver.Chrome()?

Why is driver.quit() a correctness step rather than cosmetic cleanup?

Next lesson

Build the first reproducible project

Lesson 2 turns the mental model into a disposable virtual environment, loopback fixture, pinned dependency, Manager-resolved driver, captured capabilities, assertion, screenshot, and clean teardown.

Official references and version notes

Version and compatibility note

Version-sensitive behavior was rechecked against current Selenium primary documentation on 2026-08-27. The mandatory path pins the Python binding to Selenium 4.47.0, requires Python 3.10+, uses one supported local Chromium-family browser for the runnable workflow, relies on Selenium Manager as the default driver-management path, and targets only a loopback fixture. The exact browser and driver versions are intentionally discovered from the created session rather than hard-coded. Selenium Grid, WebDriver BiDi, paid browser clouds, enterprise identity, and hosted CI are not required in Chapter 02.

Keep the academy open

Support free, practical DevOps education.

Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.

Ethereum / ERC-20
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0Send only Ethereum/ERC-20 compatible assets to this address.