QA How-To
How to Use Selenium Actions clickAndHold in Java (2026)
Learn selenium Actions clickAndHold java syntax, reliable drag gestures, waits, debugging, and interview-ready patterns with runnable Selenium examples.
18 min read | 3,184 words
TL;DR
Create an Actions instance, call clickAndHold(element), add any pointer moves, call release(), and finish with perform(). Wait for a user-visible or DOM state change instead of sleeping.
Key Takeaways
- clickAndHold presses the left pointer button but does not release it.
- End every constructed gesture with perform(), or Selenium sends no input sequence.
- Use explicit waits for the element before the gesture and for the application result after it.
- Prefer an explicit hold, move, and release chain when diagnosing drag behavior.
- Treat offsets as viewport CSS pixels and avoid unexplained coordinate constants.
- Always release a held pointer, including in cleanup after a failed intermediate assertion.
The selenium Actions clickAndHold java pattern is the WebDriver way to press and keep the left mouse button down. The shortest form is new Actions(driver).clickAndHold(element).perform(), but most real tests should complete the gesture with a move and release, then verify the application response.
This guide explains the pointer sequence, provides runnable Java examples, and shows how to remove the timing and coordinate assumptions that make drag-style tests flaky. It also distinguishes clickAndHold from click, dragAndDrop, and JavaScript event dispatch.
TL;DR
new Actions(driver)
.clickAndHold(source)
.moveToElement(target)
.release()
.perform();
| Need | Recommended call | Important detail |
|---|---|---|
| Hold one element | clickAndHold(element).perform() | The button remains down |
| Drag to another element | clickAndHold(source).moveToElement(target).release().perform() | One ordered gesture |
| Drag by distance | clickAndHold(source).moveByOffset(x, y).release().perform() | Offsets are CSS pixels |
| Simple native drag | dragAndDrop(source, target).perform() | Convenience composition |
| Normal click | click(element).perform() or element.click() | Presses and releases |
1. Selenium Actions clickAndHold Java: What the Method Actually Does
The Actions class is Selenium's high-level builder for W3C input actions. Calling clickAndHold(target) adds pointer movement to the target's center followed by a left-button down action. It does not release that button. Calling the zero-argument clickAndHold() presses at the current pointer location, so it is useful only when an earlier action established that location.
The builder detail matters. Methods such as moveToElement, clickAndHold, pause, and release enqueue steps. perform() serializes the combined input sequence and sends it to the remote end. A chain without perform() is only a Java object describing future work. This is why code can compile and appear correct while producing no browser interaction.
The event sequence is closer to a user gesture than JavaScriptExecutor code that dispatches a synthetic event. A typical chain produces pointer movement, mouseover-related events, mousedown, movement events, mouseup, and possibly click or drag-related application behavior. The exact DOM events depend on browser behavior and the application.
Use clickAndHold when the held state itself matters, when a control responds while pressed, or when you need a custom drag path. If the test only needs to activate a button, WebElement.click() communicates intent more clearly. For a broader foundation, review the Selenium Actions class guide.
2. Set Up Selenium Actions clickAndHold Java Tests
Use a current Selenium 4 Java dependency and a supported browser. Selenium Manager can resolve a compatible local driver when Chrome or Firefox is installed, so a separate driver-manager library is not required for a basic project. This Maven configuration uses Java 17, JUnit Jupiter, and the API names demonstrated in this article.
<dependencies>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>4.46.0</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.11.4</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.5.2</version>
</plugin>
</plugins>
</build>
Do not copy dependency versions blindly into a long-lived framework. Pin a version in source control, allow the dependency update process to propose changes, then run pointer tests across the browsers your product supports.
The essential imports are org.openqa.selenium.interactions.Actions, org.openqa.selenium.WebElement, and the relevant WebDriver implementation. Use WebDriverWait for readiness. Avoid mixing an implicit wait with short explicit waits because the combined timing becomes harder to reason about.
For CI, set a stable viewport. Responsive layouts can replace a desktop drag surface with touch controls or collapse a target entirely. Viewport configuration is test input, not cosmetic setup.
3. A Runnable Java clickAndHold Test
The following JUnit test loads a self-contained page, holds a button, verifies the held state, releases it, and verifies the released state. Because the page uses a data URL, the example does not rely on a third-party demo site.
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
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;
class ClickAndHoldTest {
private WebDriver driver;
@BeforeEach
void startBrowser() {
driver = new ChromeDriver();
driver.manage().window().setSize(new org.openqa.selenium.Dimension(1200, 800));
}
@AfterEach
void stopBrowser() {
if (driver != null) {
driver.quit();
}
}
@Test
void holdsAndReleasesThePointer() {
String html = """
<!doctype html>
<button id="hold">Press and hold</button>
<p id="status">idle</p>
<script>
const button = document.querySelector("#hold");
const status = document.querySelector("#status");
button.addEventListener("mousedown", () => status.textContent = "held");
button.addEventListener("mouseup", () => status.textContent = "released");
</script>
""";
String encoded = Base64.getEncoder().encodeToString(
html.getBytes(StandardCharsets.UTF_8));
driver.get("data:text/html;base64," + encoded);
WebElement button = driver.findElement(By.id("hold"));
WebElement status = driver.findElement(By.id("status"));
new Actions(driver).clickAndHold(button).perform();
assertEquals("held", status.getText());
new Actions(driver).release(button).perform();
assertEquals("released", status.getText());
}
}
This two-call example intentionally proves that the held state persists between perform() calls. For a drag, one composite chain is usually safer because the ordered actions are sent together. If an assertion between hold and release fails, release the pointer in a finally block or recreate the session so later tests do not inherit an uncertain input state.
4. clickAndHold, click, and dragAndDrop Compared
Choosing the most specific API makes failures easier to understand.
| API | Pointer sequence | Best use | Main risk |
|---|---|---|---|
| WebElement.click() | Move is implementation-managed, then down and up | Buttons, links, checkboxes | Interception by overlays |
| Actions.click(element) | Move to center, down, up | A click inside a larger action chain | Missing perform() |
| Actions.clickAndHold(element) | Move to center, down | Press state and custom gestures | Forgotten release |
| Actions.dragAndDrop(source, target) | Hold source, move to target, release | Simple source-to-target movement | Less visibility into intermediate steps |
| JavaScript event dispatch | Application-defined synthetic event | Rare instrumentation or app-specific fallback | Does not prove real pointer behavior |
dragAndDrop is a convenience composition. Expanding it to clickAndHold, moveToElement, and release is useful when you need a pause, an intermediate waypoint, an offset, or diagnostics around one step. It does not guarantee that every HTML5 drag-and-drop library will accept the gesture. Some libraries require a minimum movement threshold, specific pointer coordinates, or application state that appears only after mousedown.
Do not present JavaScript as a universal fix. A synthetic drop may make the DOM change while bypassing hit testing and pointer behavior. That can hide the exact integration defect an end-to-end test should catch.
5. Build Reliable Drag, Slider, and Press Gestures
A robust source-to-target gesture locates stable elements, waits until the source can receive input, sends one ordered sequence, and waits for a meaningful result.
WebElement card = wait.until(
org.openqa.selenium.support.ui.ExpectedConditions.elementToBeClickable(
By.cssSelector("[data-testid='card-42']")));
WebElement lane = wait.until(
org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated(
By.cssSelector("[data-testid='lane-done']")));
new Actions(driver)
.moveToElement(card)
.clickAndHold()
.pause(java.time.Duration.ofMillis(150))
.moveToElement(lane)
.pause(java.time.Duration.ofMillis(150))
.release()
.perform();
wait.until(d -> lane.findElements(
By.cssSelector("[data-card-id='42']")).size() == 1);
The short pauses are justified only if the component requires time to enter its drag mode or render the drop affordance. They are not replacements for readiness waits. Start without pauses, add the smallest documented interaction delay when the UI requires one, and comment on the reason.
For a slider, compute the displacement from the rendered rail and the domain, rather than storing a pixel from one laptop. If a 200 CSS-pixel rail represents 0 through 100 and the requested change is 25 points, the illustrative displacement is 50 pixels. Account for the thumb width and the component's rounding rule, then verify the displayed value or an accessibility attribute such as aria-valuenow.
For canvas controls, WebDriver cannot locate shapes inside the bitmap. Move to a stable canvas-relative offset, hold, move by an explicitly calculated offset, release, and verify an external state. Document the coordinate transform in a helper.
6. Synchronization for Selenium Actions clickAndHold Java
There are two synchronization boundaries. Before the gesture, wait for the element and surrounding UI to be ready. After the gesture, wait for the business result. Sleeping for a guessed interval combines both boundaries into one fragile delay.
Before input, check conditions relevant to the product: the source is visible, enabled, and not covered; the target exists; an animation has ended; or a loading mask is absent. elementToBeClickable checks visibility and enabled state, but it cannot guarantee that another element will not intercept the pointer at the center. A product-specific wait for the overlay to disappear is often more valuable.
After input, assert a durable result. Good examples include an item appearing in a destination list, an aria-valuenow change, a saved state message, or a network-backed status becoming complete. Avoid asserting only that the pointer moved. Pointer motion is a mechanism, not the user outcome.
When the source is replaced by a re-render, a stored WebElement becomes stale. Locate it after the state transition that creates the final version. Do not catch StaleElementReferenceException and retry the whole gesture blindly, because the first attempt may already have changed the application. Retrying non-idempotent drag operations can move an item twice or reorder a list unexpectedly. The explicit waits in Selenium Java guide covers condition design in more depth.
7. Put clickAndHold in Maintainable Java Test Code
Keep pointer mechanics in a component object and business assertions in the test. The helper should accept semantic targets, expose no unexplained sleeps, and leave the pointer released when it returns.
public final class KanbanBoard {
private final WebDriver driver;
private final WebDriverWait wait;
public KanbanBoard(WebDriver driver) {
this.driver = driver;
this.wait = new WebDriverWait(driver, java.time.Duration.ofSeconds(8));
}
public void moveCard(String cardId, String laneId) {
By cardBy = By.cssSelector("[data-card-id='" + cardId + "']");
By laneBy = By.cssSelector("[data-lane-id='" + laneId + "']");
WebElement card = wait.until(
org.openqa.selenium.support.ui.ExpectedConditions.elementToBeClickable(cardBy));
WebElement lane = wait.until(
org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated(laneBy));
new Actions(driver)
.clickAndHold(card)
.moveToElement(lane)
.release()
.perform();
wait.until(d -> lane.findElements(cardBy).size() == 1);
}
}
This API tells the test what happened: move card 42 to done. If different board implementations need different paths, keep that variation inside the board component. Do not create a global actions utility with dozens of unrelated parameters. Such a utility hides page context and usually spreads pixel offsets through the suite.
Create a fresh Actions builder for each logical gesture. The Java builder resets after build(), but a short-lived object still makes the intended sequence obvious and avoids accidental coupling between helpers.
8. Diagnose clickAndHold When It Does Not Work
Start with evidence, not extra sleeps. Capture a screenshot before and after the gesture, record the source and target rectangles, and inspect whether an overlay occupies the center point. Browser console and network failures can explain why a drop handler never initialized.
Check the failure in this order:
- Confirm perform() is called.
- Confirm the locator returns the intended visible instance, not a hidden responsive duplicate.
- Confirm the source center is inside the interactive hit area.
- Confirm the element is in the correct frame and window.
- Confirm the target remains attached during the gesture.
- Confirm the component supports mouse or pointer input in the tested layout.
- Compare an explicit hold, move, release chain with dragAndDrop.
MoveTargetOutOfBoundsException usually indicates a bad offset, an unexpected viewport, or a target whose calculated point is outside the current viewport. ElementClickInterceptedException points to hit testing, commonly an overlay or animation. StaleElementReferenceException means the underlying node was replaced. Treat those as different defects.
If the gesture works locally but fails remotely, log browser version, driver version, viewport, device scale factor, and the resolved element rectangles. Video is helpful, but structured state usually makes the root cause faster to reproduce.
9. Cross-Browser, Accessibility, and Test Scope
Run critical pointer gestures in every supported browser, because event ordering and drag implementations can expose product differences. Keep the assertion browser-neutral. The product should report the same final state even if intermediate implementation events differ.
Also test the keyboard path. A sortable control, slider, or movable card should often have an accessible keyboard interaction. The pointer test proves mouse behavior. A separate keyboard test proves operability without a mouse. Do not use clickAndHold as a substitute for an accessibility check.
Choose the right test layer. Unit or component tests can exhaustively verify drag calculations and state reducers. A smaller number of WebDriver tests should prove that browser input reaches the integrated component and persists the result. This balance reduces maintenance while preserving user-level confidence.
Mobile emulation does not turn Actions mouse input into a complete touch test. If the requirement is touch behavior, use tooling and a browser or device path that actually exercises touch or pen input. Name the test according to the input modality it covers.
10. A Production Checklist for Selenium Actions clickAndHold Java
Before merging a hold or drag test, review the following:
- Use a stable, user-facing locator or test ID for both source and target.
- Wait for the final interactive element after re-renders.
- Set and record the viewport used by the scenario.
- Prefer one composite sequence for hold, move, and release.
- Explain any pause or coordinate calculation.
- Verify a business or accessibility state after release.
- Ensure failure cleanup cannot leave the pointer depressed.
- Run the test on the browser matrix appropriate to the feature.
- Collect screenshot, rectangles, and application logs on failure.
A helper can use a try-finally strategy only with care. If perform() throws midway, sending release() may help restore the input source, but the browser or remote end may already consider the sequence complete or failed. For strict isolation, create a fresh session after an unrecoverable input-state failure. In normal successful paths, always make release explicit.
Keep drag tests focused. One test should not move ten cards merely to reach an assertion. Prepare state through an API or fixture when that does not bypass the behavior under test, perform one representative gesture, then verify persistence. See Selenium framework design for Java for boundaries between setup, page components, and assertions.
11. Test True Press-and-Hold Behavior, Not Only Dragging
clickAndHold is also useful when time spent in the pressed state is the requirement. Examples include a hold-to-confirm control, a repeating stepper button, a press preview, or a safety action that activates only after a threshold. Model the complete state machine rather than forcing the scenario into drag-and-drop language.
First, confirm the product requirement defines the hold duration and cancellation behavior. Queue clickAndHold and a documented pause when the input protocol must maintain the button for that interval, then release and assert the confirmed state. Create a separate negative scenario that releases before the threshold and verifies that no confirmation occurs. Keep timing tolerances at the component or integration layer when possible, since end-to-end scheduling is not a precision clock.
Also test cancellation paths. Moving outside the control, losing window focus, or receiving Escape may cancel depending on the component contract. Do not assume mouseup inside the element is the only exit. Assertions should inspect the visible state, saved result, or accessibility announcement, not the number of DOM events.
For destructive actions, never run hold-to-confirm tests against uncontrolled shared data. Create an isolated record and prove both confirmation and early-release cancellation. This turns a low-level pointer method into requirement-focused coverage.
12. Preserve Pointer Isolation Across the Test Suite
Input state is session state. A failed test that pressed without releasing can make the next click behave unpredictably, especially when a framework reuses one browser for several methods. The most reliable policy is a fresh driver per test or a well-defined scenario scope. Speed gained by broad session reuse rarely justifies cross-test pointer coupling.
If reuse is unavoidable, keep every normal gesture complete in a single chain and run cleanup in a framework boundary. A best-effort release can restore a known state after an assertion failure between separate perform calls, but it is not guaranteed recovery after a transport or browser error. Mark that session unusable and recreate it when the input protocol fails.
Parallel execution needs the same rule: never share an Actions instance or WebDriver across test threads. Each browser has its own input source state, viewport, page, and listener timeline. Make component objects driver-scoped and avoid static WebElements.
Finally, include one small pointer contract test in CI. It should hold, observe the held state, release, and observe the released state on a self-contained page. When a browser or Selenium upgrade breaks that contract test, you can diagnose the environment before investigating every product drag scenario.
Interview Questions and Answers
Q: What does clickAndHold do in Selenium Java?
It moves to the supplied element's center and presses the left pointer button without releasing it. The action is queued until perform() executes the sequence. A later release is required for a complete drag-style gesture.
Q: Why does a chained Actions statement sometimes do nothing?
Actions is a builder. Without perform(), the calls only describe an input sequence in memory. build().perform() is also valid, but calling perform() directly is clearer for most one-off gestures.
Q: What is the difference between clickAndHold(element) and moveToElement(element).clickAndHold()?
For the Java Actions API, they express the same target behavior. The explicit move form can be easier to extend with a pause or a diagnostic waypoint. The zero-argument clickAndHold depends on the current pointer position.
Q: When would you use clickAndHold instead of dragAndDrop?
Use it when the gesture needs intermediate movement, offsets, pauses required by the component, or clearer troubleshooting. dragAndDrop is concise for a simple source-to-target gesture. Both still require perform().
Q: How do you make a drag test less flaky?
Wait for source and target readiness, use stable locators, send one composite sequence, and wait for a durable result after release. Avoid arbitrary sleeps and unexplained fixed pixels. Capture rectangles and overlays when it fails.
Q: What should a test assert after clickAndHold?
Assert the behavior required by the scenario. For a press control, that may be a held state before release. For a drag, assert destination membership, persisted order, or an accessible value after release.
Q: Can JavaScriptExecutor replace Actions for drag and drop?
It can trigger application-specific code, but it is not equivalent to real pointer input. Use it only when the test goal explicitly concerns that script path or as a documented diagnostic. It should not silently replace the end-to-end pointer check.
Common Mistakes
- Forgetting perform(): No queued input is sent to the browser.
- Forgetting release(): Later actions can start from an uncertain pointer state.
- Using release without a prior hold: Selenium documents this as undefined behavior.
- Sleeping instead of waiting for state: A fixed delay can be both slow and insufficient.
- Dragging a stale element: Re-locate after the render that creates the final node.
- Treating pixels as business values: Calculate offsets from component geometry and domain rules.
- Catching every exception and retrying: A drag may be non-idempotent, so a retry can change state twice.
- Asserting only visual motion: Verify the user or business outcome.
- Using a hidden duplicate element: Responsive pages often render multiple matching controls.
- Replacing pointer input with JavaScript: Synthetic events can bypass real hit testing.
Conclusion
The reliable selenium Actions clickAndHold java approach is simple in principle: identify a ready source, press with clickAndHold, move if the scenario requires it, release, call perform(), and verify a durable result. Most failures come from missing execution, unstable elements, hidden overlays, or coordinate assumptions rather than from the method itself.
Start with the runnable held-state test, then adapt the gesture inside a focused page component. Add only the pauses and offsets your product behavior actually requires.
Interview Questions and Answers
Explain clickAndHold in the Selenium Java Actions API.
clickAndHold queues a left-button pointer-down at the supplied element's center, or at the current pointer location when no element is supplied. It does not release the button. perform() is required to send the sequence to the browser.
Why is perform() required with Actions?
Actions uses the builder pattern. Each fluent method adds input ticks to a composite sequence, while perform() builds and executes that sequence through WebDriver. Without it, no browser input occurs.
How would you implement a custom drag in Java?
Wait for source and target, then chain clickAndHold(source), moveToElement(target), release(), and perform(). Add an intermediate pause or waypoint only when the component needs it, and assert the final application state.
How do clickAndHold(element) and clickAndHold() differ?
The element overload moves to the target center before pressing. The no-argument overload presses at the current pointer location, so it depends on an earlier movement and is easier to misuse in isolation.
What makes pointer-action tests flaky?
Common causes are animation, overlays, stale elements, responsive duplicates, unrecorded viewport changes, and fixed offsets. Reliable tests synchronize around application state and collect geometry on failure.
Would you retry a failed drag automatically?
Not by default, because a drag can be non-idempotent and the first attempt may have changed state. I would determine the state, restore a known precondition, and only then retry through a controlled framework policy.
How would you test accessibility for a draggable component?
I would keep the mouse gesture test and add a separate keyboard-operability test using the product's supported keys. I would also verify relevant roles, names, states, and value attributes rather than assuming mouse support proves accessibility.
Frequently Asked Questions
How do I click and hold an element in Selenium Java?
Create new Actions(driver), call clickAndHold(element), and finish with perform(). If the scenario continues into a drag, add moveToElement or moveByOffset, then release before perform().
Does Selenium clickAndHold release the mouse automatically?
No. clickAndHold leaves the left pointer button depressed. Add release() or release(target) to complete the gesture and prevent uncertain input state.
Why is clickAndHold not working in Selenium?
First check that perform() is present and that the locator resolves to the visible interactive element. Then inspect overlays, frames, stale elements, viewport size, and whether the component requires movement past a drag threshold.
What is the difference between clickAndHold and dragAndDrop?
clickAndHold is one pointer-down step that you can combine with custom movement and release. dragAndDrop is a convenience sequence for holding a source, moving to a target, and releasing.
Can I use clickAndHold without an element?
Yes. The zero-argument form presses at the current pointer location. Establish that location with moveToElement or another movement first so the gesture is deterministic.
Should I add pause after clickAndHold?
Only when the component has a documented or observed press-to-drag transition. Prefer waiting for application state outside the sequence, and keep any necessary pause short and explained.
How do I verify a Selenium drag succeeded?
Assert a durable outcome such as destination membership, persisted order, displayed value, or an accessibility attribute. Do not treat successful execution of perform() as proof of the business result.
Related Guides
- How to Use Selenium Actions moveToElement in Java (2026)
- How to Use Selenium DevTools in Selenium 4 in Java (2026)
- How to Use Selenium BiDi network in Java (2026)
- How to Use Selenium browser console logs in Java (2026)
- How to Use Selenium By cssSelector in Java (2026)
- How to Use Selenium By xpath dynamic in Java (2026)