The Katalon Blog

Double Click in Selenium: Java & Python Examples

Written by Joe Sturgess | Sep 12, 2025, 3:30:00 PM

A double click looks like the simplest edge case in Selenium's API: call one method instead of click(), and move on. It rarely stays that simple, the interaction depends on a genuine dblclick browser event, not two clicks fired back to back. Get that distinction wrong and a test can pass locally while never actually exercising the behavior it was meant to check.

This guide puts double click first, since it is the interaction most teams reach for and the one with the most ways to go wrong, then covers right click as the related interaction it is. Here is what we will cover:

  • Why doubleClick() is not the same as calling click() twice
  • How to perform a double click in Selenium, in Java and Python, with a wait and an assertion, not just the click itself
  • Selenium click vs. double-click vs. right-click, compared
  • How to right-click (context click) in Selenium, and where it differs from a double click
  • What actually breaks a double-click or right-click test, and how to fix each failure

THE SHORT ANSWER

How to double click in Selenium, at a glance:
• Use the Actions class: doubleClick() for a double click (contextClick() for the related right-click case). Both mirror the same way in Python through ActionChains.
• Wait for elementToBeClickable first. A double click on an element that is not yet interactable fails the same way a single click does.
• Do not replace doubleClick() with two calls to click(). Browsers only fire a native dblclick event when both clicks land inside a short time window, and two separate Selenium clicks will not reliably do that.
• A test that passes locally but fails in CI is usually a headless-mode or viewport difference, not a broken locator.

 

The examples, comparison, and troubleshooting section below cover each of these in depth.

Why a Double Click Is Not Two Single Clicks

It is tempting to reach for element.click(); element.click(); and assume the browser will treat it as a double click. It usually will not. A real double click is its own DOM event, dblclick, and the browser only fires it when it registers two clicks on the same element inside a short, fixed time window. Two Selenium clicks issued in a script often land outside that window, or register as two independent single clicks instead of one double click, so any UI logic listening specifically for dblclick (inline text editing, expanding a row, selecting a word) never fires.

Selenium's Actions class solves this by synthesizing the double click as a single, correctly timed browser event rather than two separate ones. That is the whole reason doubleClick() exists as a distinct method instead of a convenience wrapper around click().

How to Double Click in Selenium: Java and Python

A realistic double-click scenario is an expandable row: double-clicking a row in a data grid reveals its line-item detail without navigating to a new page. The selectors below (order-1024-row, order-details-expanded) are sample IDs for a generic grid, standing in for whatever grid or list your own app uses, not live elements on katalon.com. Below is a complete test: wait for the row to be interactable, double-click it, then assert the detail panel actually appeared. Stopping at the click itself hides the part that matters, confirming the double click did something.

Java
import java.time.Duration;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

WebDriver driver = new ChromeDriver();
driver.get("https://katalon.com");

WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
WebElement orderRow = wait.until(
    ExpectedConditions.elementToBeClickable(By.id("order-1024-row"))
);

new Actions(driver).doubleClick(orderRow).perform();

WebElement detailsPanel = wait.until(
    ExpectedConditions.visibilityOfElementLocated(By.className("order-details-expanded"))
);
Assertions.assertTrue(detailsPanel.isDisplayed(), "Double-click did not expand the order row");

driver.quit();
Python
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

driver = webdriver.Chrome()
driver.get("https://katalon.com")

wait = WebDriverWait(driver, timeout=10)
order_row = wait.until(EC.element_to_be_clickable((By.ID, "order-1024-row")))

ActionChains(driver).double_click(order_row).perform()

details_panel = wait.until(EC.visibility_of_element_located((By.CLASS_NAME, "order-details-expanded")))
assert details_panel.is_displayed(), "Double-click did not expand the order row"

driver.quit()

The Java example asserts with Assertions.assertTrue() from JUnit 5 rather than Java's built-in assert keyword, which needs the JVM's -ea flag to run at all and otherwise silently passes even on a real failure. For why the elementToBeClickable wait matters here specifically, see our guide to explicit wait in Selenium.

Selenium Click vs. Double-Click vs. Right-Click

All three trigger through the same WebElement, but they fire different browser events and fail in different ways.

  Selenium Click Events, Compared
Same WebElement, three different browser events, three different failure modes.
click() Fires a single click event. The default for buttons, links, and anything a real user would click once. Fails with ElementClickInterceptedException if something else sits on top of the element.
doubleClick() Fires a genuine dblclick event through the Actions class. Needed for UI patterns that specifically listen for it: expanding a row, selecting text, opening a file. Two calls to click() will not reliably trigger it.
contextClick() Fires a contextmenu event through the Actions class. Only useful against a menu your application renders itself; the browser's native right-click menu is a separate OS-level surface Selenium cannot see or interact with.

For the broader family, including Actions.click() and a JavaScript executor click, see our guide to the Selenium click command.

How to Right-Click (Context Click) in Selenium

Right-click is the related interaction: same Actions pattern, useful for testing file managers, editors, or any UI that reveals a secondary menu instead of navigating away. As the table above notes, this only works if your app renders its own menu, not the browser's native one.

Java
WebDriver driver = new ChromeDriver();
driver.get("https://katalon.com");

WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
WebElement fileIcon = wait.until(
    ExpectedConditions.elementToBeClickable(By.id("attachment-icon"))
);

new Actions(driver).contextClick(fileIcon).perform();

WebElement menu = wait.until(
    ExpectedConditions.visibilityOfElementLocated(By.className("context-menu"))
);
Assertions.assertTrue(menu.isDisplayed(), "Right-click did not open the context menu");
Python
driver = webdriver.Chrome()
driver.get("https://katalon.com")

wait = WebDriverWait(driver, timeout=10)
file_icon = wait.until(EC.element_to_be_clickable((By.ID, "attachment-icon")))

ActionChains(driver).context_click(file_icon).perform()

menu = wait.until(EC.visibility_of_element_located((By.CLASS_NAME, "context-menu")))
assert menu.is_displayed(), "Right-click did not open the context menu"

attachment-icon and context-menu are sample selectors for illustration, the same wait-then-assert pattern applies whatever your app's actual menu markup looks like.

Troubleshooting: When Double-Click and Right-Click Interactions Fail

The syntax is rarely the problem. These are the failures that actually show up in real test runs.

Element not interactable, or the double click silently does nothing. If the element is present in the DOM but not yet visible or enabled, doubleClick() fails the same way click() does. Wait for elementToBeClickable, not just presence, before performing the action.

ElementClickInterceptedException from an overlay. A cookie banner, sticky header, or modal sitting on top of the target intercepts the interaction. Scroll the element into an uncovered part of the page, then retry the wait and the double click or right click.

StaleElementReferenceException right after a right-click. If opening a context menu re-renders part of the DOM, your reference to the original element can go stale. Re-locate the element (or the menu) after the interaction rather than reusing a handle captured before it.

Passes locally, fails in CI or headless mode. Headless browsers and CI runners often use a different default viewport size than your local machine, which changes what is actually visible or hoverable at a given point on the page. If a double click or right click depends on a hover state to reveal the target first, set an explicit window size in your CI configuration and confirm the element is genuinely visible before interacting with it, not just present.

When not to reach for a JavaScript executor. A JavaScript click bypasses Selenium's visibility and interactability checks, but it cannot synthesize a real dblclick or contextmenu event the way Actions can. Using it here does not just risk masking a real bug, it can fail to trigger the UI behavior you are testing at all. Reserve it for scrolling elements into view, and use Actions for the interaction itself.

Best Practices Checklist

  • Wait for elementToBeClickable before every double click or right click, not just presence in the DOM.
  • Never substitute two click() calls for doubleClick().
  • Assert on the result of the interaction (a panel expanding, a menu appearing), not just that the method call did not throw.
  • Confirm a right-click target is an app-rendered menu before writing the test; Selenium cannot assert against the browser's native menu.
  • Re-locate elements after an interaction that changes the DOM, rather than reusing a reference captured beforehand.
  • Match your CI runner's viewport size to local if a hover state or visibility check is part of the interaction.

How Katalon Simplifies Double-Click Testing

Katalon is a low-code automation platform built on top of Selenium. For an interaction like a double click, that mostly means removing the boilerplate around it, not the interaction itself: instead of hand-writing an Actions chain plus wait logic every time, you reuse a saved test object for the target row and a built-in wait keyword, then inspect a screenshot or video of the exact moment the double click fired if it fails, rather than re-running the test to find out why.

  • Object Repository: the row or element you are targeting lives in one place and gets reused across test cases, instead of a locator string duplicated in every script.
  • Built-in wait keywords: keywords like WebUI.waitForElementClickable handle the same interactability check this guide's examples wait for manually.
  • Simplified action steps: double-click (and right-click) are available as single keyword-driven steps, without hand-writing the Actions chain each time.
  • Cross-browser execution: the same interaction test runs across Chrome, Firefox, Safari, and Edge, useful given how much this behavior can vary by browser and headless configuration.

To go deeper, the free Using Built-in Keywords in Katalon course covers test objects and reusable keywords in full.