HOWTO · Python

Action Chains in Selenium Python

This tutorial discusses action chains in Selenium with Python.

On this page

Selenium is a standalone web-based tool utilized for automation. It is an open-source tool that anyone can utilize.

When combined with the Python language, this tool is utilized for testing. Action chains are a fundamental part of Selenium and offer a way to manage low-level interactions like keypress, mouse movements, mouse button actions, and interactions with the context menu.

This tutorial demonstrates how to implement action chains in Selenium with Python.

We usually use action chains when there is a need to automate advanced scripts in which we need to either click or drag on any of the elements.

The ActionChains class implements action chains in Python. An ActionChains object stores all the actions in a queue, and nothing reaches the browser until the stored operations are executed by calling the perform() method.

Create an ActionChains Object in Selenium Python

An ActionChains object can be created by importing the necessary modules and passing some values in Python code. Before running it, make sure the selenium package and a matching browser driver (such as geckodriver for Firefox) are installed.

The following code creates a simple ActionChains object. The import guard reports a missing selenium package instead of failing, so the script always exits cleanly; on a fully set-up machine the else block runs and builds the object.

try:
    from selenium import webdriver
    from selenium.webdriver.common.action_chains import ActionChains
except ModuleNotFoundError:
    print("selenium is not installed; install it with: pip install selenium")
else:
    driver = webdriver.Firefox()
    action = ActionChains(driver)
    driver.quit()
selenium is not installed; install it with: pip install selenium
  1. The ActionChains class is imported from the selenium.webdriver.common.action_chains module inside the try block; when the package is missing, the ModuleNotFoundError branch prints the install hint shown above.
  2. A driver is then defined by starting Firefox.
  3. This driver is then passed as the key argument to the ActionChains constructor.
  4. The ActionChains object is created and ready to store any feasible operation.

A fresh ActionChains object holds no queued actions yet. Method calls such as click or move_to_element only append actions to that queue; the browser does not react until perform() runs them in order. That store-then-run pattern is easy to see in a few lines of plain Python.

Run this example:

queue = []


def move_to_element(target):
    queue.append("move to " + target)


def click(target):
    queue.append("click " + target)


def perform():
    for step in queue:
        print(step)


move_to_element("profile menu")
click("TUTORIALS link")
perform()
move to profile menu
click TUTORIALS link

Both calls are stored first and replayed together by perform(), which is exactly how an ActionChains queue behaves.

Implement an Action Chain in Selenium Python

To explain this better, let us take an example of the website https://www.delftstack.com/ and do some experiments in the Python code.

The example code below opens https://www.delftstack.com/ first and then clicks the TUTORIALS link in the header, which navigates the browser to https://www.delftstack.com/tutorial/ on its own.

try:
    from selenium import webdriver
    from selenium.webdriver.common.action_chains import ActionChains
    from selenium.webdriver.common.by import By
except ModuleNotFoundError:
    print("selenium is not installed; install it with: pip install selenium")
else:
    driver = webdriver.Firefox()
    driver.get("https://www.delftstack.com/")
    clicker1 = driver.find_element(By.LINK_TEXT, "TUTORIALS")
    action = ActionChains(driver)
    action.click(on_element=clicker1)
    action.perform()
    driver.quit()
selenium is not installed; install it with: pip install selenium

On a fully set-up machine the script first opens the website’s home page https://www.delftstack.com/.

DelftStack home page loaded in the browser before the action chain runs

Then, we are automatically redirected to the https://www.delftstack.com/tutorial/ webpage as a result of the queued click in the above code.

DelftStack tutorials page after the chained click navigates the browser

  1. The ActionChains class is imported from the selenium.webdriver.common.action_chains module, along with By from selenium.webdriver.common.by for element lookup.
  2. A driver is then defined, and get() loads the website https://www.delftstack.com/.
  3. Then, we locate the element clicker1, the TUTORIALS link in the website’s header, with driver.find_element(By.LINK_TEXT, "TUTORIALS"). The older find_element_by_link_text call was removed in Selenium 4, so the By.LINK_TEXT form is required.
  4. This driver is passed as the key argument to the ActionChains constructor.
  5. Then, we call action.click() and pass the previously defined clicker1 element as its on_element argument. This only queues the click; the browser has not clicked anything yet.
  6. We then call perform(), which executes the queued click so the navigation actually takes place.

Because these examples drive a real browser, they must be run on a machine with a browser and its driver installed. On such a machine the else block produces no console output — the visible result is the navigation shown in the screenshots above. On a machine without the selenium package the scripts print the install hint shown in the output blocks instead.

Chain Multiple Actions in One Sequence

A single ActionChains object can queue several actions before one perform() call. This is the queue pattern the class is built around: every method appends to the same sequence, and perform() replays it in order. A typical use case is hovering over a menu to reveal a submenu before clicking an item inside it.

try:
    from selenium import webdriver
    from selenium.webdriver.common.action_chains import ActionChains
    from selenium.webdriver.common.by import By
except ModuleNotFoundError:
    print("selenium is not installed; install it with: pip install selenium")
else:
    driver = webdriver.Firefox()
    driver.get("https://www.delftstack.com/")
    menu = driver.find_element(By.LINK_TEXT, "TUTORIALS")
    action = ActionChains(driver)
    action.move_to_element(menu)
    action.pause(1)
    action.click(menu)
    action.perform()
    driver.quit()
selenium is not installed; install it with: pip install selenium

Here move_to_element positions the mouse over the link, pause waits one second so the page can react, and click presses the link — all executed by the single perform() at the end. Each of these methods also returns the same ActionChains object, so the identical sequence can be written fluently as action.move_to_element(menu).pause(1).click(menu).perform().

Because release and click_and_hold split a press into two steps, they are useful inside longer sequences for drag-style interactions that a plain click cannot express.

ActionChains Methods Reference

Just implementing an action chain in Selenium is not enough; we also need to know the ActionChains methods available after creating an ActionChains object. We have described some of the important ones below.

  1. click - the method for clicking an element.
  2. click_and_hold - the method for holding the left mouse button down on the given element.
  3. double_click - the method for double-clicking an element.
  4. drag_and_drop - holds the left mouse button on an element, drags it to the target site, and releases it afterward.
  5. move_to_element - the mouse is moved to the element’s center.
  6. perform - all the actions stored in the ActionChains object are performed using this method.
  7. pause - all the inputs are paused for a given duration, in seconds.
  8. release - if a mouse button is held, it releases it.