Python Selenium Web Driver Complete Tutorial

Written by

in

Welcome to the ultimate Python Selenium WebDriver complete tutorial! Whether you’re a beginner eager to automate your first browser test or an experienced QA engineer looking to sharpen your skills, this guide covers everything you need—from installation to advanced best practices. By the end of this article, you’ll be able to write robust, maintainable Selenium scripts in Python that can handle dynamic web pages, multiple browsers, and real‑world test scenarios.

Why Choose Selenium with Python?

Selenium is the de‑facto standard for web automation, and Python’s clean syntax makes it an ideal partner. Together they provide:

  • Cross‑browser support: Chrome, Firefox, Edge, Safari, and headless browsers.
  • Rich ecosystem: Integration with pytest, unittest, and CI/CD pipelines.
  • Ease of learning: Python’s readability speeds up script development.
  • Community power: Thousands of tutorials, plugins, and Stack Overflow answers.

Prerequisites

Before diving in, make sure you have the following installed on your machine:

  • Python 3.8+ (download from python.org)
  • pip (Python package manager, included with Python)
  • A supported web browser (Chrome, Firefox, Edge, etc.)
  • Corresponding browser driver (ChromeDriver, GeckoDriver, etc.)

Step 1: Installing Selenium

Open a terminal or command prompt and run the pip command:

pip install selenium

This installs the latest stable Selenium 4.x release, which includes the new webdriver manager and enhanced relative locators.

Step 2: Setting Up the WebDriver

Selenium requires a driver executable that acts as a bridge between Python code and the browser. You can manage drivers manually or let Selenium handle them automatically.

2.1 Manual Driver Management

  1. Download the driver that matches your browser version:
  2. Extract the executable to a folder on your system PATH or note the full path.
  3. Instantiate the driver in your script, for example:
from selenium import webdriver

driver = webdriver.Chrome(executable_path="/path/to/chromedriver")
driver.get("https://www.example.com")

2.2 Automatic Driver Management (Recommended)

Selenium 4 introduces webdriver-manager which downloads the correct driver on the fly.

pip install webdriver-manager

Then use it like this:

from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager

driver = webdriver.Chrome(ChromeDriverManager().install())
driver.get("https://www.example.com")

This approach eliminates version mismatches and works across CI environments.

Basic Selenium Commands

Once the driver is ready, you can perform a variety of actions. Below are the most frequently used commands.

  • Navigate: driver.get(url), driver.back(), driver.forward(), driver.refresh()
  • Window Management: driver.maximize_window(), driver.set_window_size(width, height)
  • Cookies: driver.get_cookies(), driver.add_cookie(dict), driver.delete_all_cookies()
  • Quit: driver.quit() (closes all windows and ends the session)

Locating Elements

Finding the right element is the cornerstone of any Selenium script. Selenium 4 supports several locator strategies:

  • By.ID
  • By.NAME
  • By.XPATH
  • By.CSS_SELECTOR
  • By.CLASS_NAME
  • By.TAG_NAME
  • By.LINK_TEXT / By.PARTIAL_LINK_TEXT

Example using By.CSS_SELECTOR:

from selenium.webdriver.common.by import By

search_box = driver.find_element(By.CSS_SELECTOR, "input[name='q']")
search_box.send_keys("Python Selenium tutorial")
search_box.submit()

Relative Locators (New in Selenium 4)

Relative locators let you find elements based on their position to other known elements.

from selenium.webdriver.common.by import By
from selenium.webdriver.support.relative_locator import locate_with

# Find an element below the logo
below_logo = driver.find_element(locate_with(By.TAG_NAME, "input").below({"id": "logo"}))

Explicit and Implicit Waits

Web pages often load content asynchronously. Relying on time.sleep() makes tests flaky. Selenium provides two robust waiting mechanisms.

Implicit Wait

Sets a global timeout for all find_element calls.

driver.implicitly_wait(10)  # seconds

Explicit Wait

Waits for a specific condition before proceeding.

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

wait = WebDriverWait(driver, 15)
login_button = wait.until(EC.element_to_be_clickable((By.ID, "login")))
login_button.click()

Handling Common Web Elements

2.1 Alerts and Pop‑ups

alert = driver.switch_to.alert
alert.accept()          # Click OK
# or
alert.dismiss()         # Click Cancel
# or send text
alert.send_keys("Sample input")

2.2 Frames and iFrames

# Switch to a frame by name or index
driver.switch_to.frame("frameName")
# Perform actions inside the frame
driver.find_element(By.TAG_NAME, "button").click()
# Return to the default content
driver.switch_to.default_content()

2.3 Multiple Windows/Tabs

# Open a new tab
driver.execute_script("window.open('https://www.google.com');")
# Switch to the new window
driver.switch_to.window(driver.window_handles[1])
# Do something
driver.title
# Close and return
driver.close()
driver.switch_to.window(driver.window_handles[0])

2.4 Taking Screenshots

# Full page screenshot (available in recent Selenium versions)
driver.save_screenshot("homepage.png")

# Element screenshot
logo = driver.find_element(By.ID, "logo")
logo.screenshot("logo.png")

Organizing Tests with the Page Object Model (POM)

The Page Object Model separates page structure from test logic, making scripts easier to maintain.

# file: pages/login_page.py
from selenium.webdriver.common.by import By

class LoginPage:
    def __init__(self, driver):
        self.driver = driver
        self.username_input = (By.ID, "username")
        self.password_input = (By.ID, "password")
        self.login_btn = (By.CSS_SELECTOR, "button.login")

    def load(self):
        self.driver.get("https://example.com/login")

    def login(self, user, pwd):
        self.driver.find_element(*self.username_input).send_keys(user)
        self.driver.find_element(*self.password_input).send_keys(pwd)
        self.driver.find_element(*self.login_btn).click()

Test script using the page object:

# file: tests/test_login.py
import unittest
from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
from pages.login_page import LoginPage

class LoginTest(unittest.TestCase):
    def setUp(self):
        self.driver = webdriver.Chrome(ChromeDriverManager().install())
        self.login_page = LoginPage(self.driver)

    def test_valid_login(self):
        self.login_page.load()
        self.login_page.login("admin", "secret")
        self.assertIn("Dashboard", self.driver.title)

    def tearDown(self):
        self.driver.quit()

if __name__ == "__main__":
    unittest.main()

Best Practices for Stable Selenium Scripts

  • Use explicit waits instead of static sleeps.
  • Prefer CSS selectors over complex XPaths for speed and readability.
  • Encapsulate locators in page objects or separate constants.
  • Run tests in headless mode on CI servers to save resources:
    options = webdriver.ChromeOptions()
    options.add_argument("--headless")
    driver = webdriver.Chrome(ChromeDriverManager().install(), options=options)
  • Parameterize data using fixtures (pytest) or data‑driven approaches.
  • Log actions with Python’s logging module for easier debugging.

Common Errors and How to Fix Them

Error Typical Cause Solution
SessionNotCreatedException Driver version mismatch with browser Update driver via webdriver-manager

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *