Selenium WebDriver core API for automating web browsers across different platforms and programming languages.
—
The Actions class provides advanced interaction capabilities including mouse actions, keyboard input, drag-and-drop operations, and action chaining for complex user workflows.
Advanced interaction builder for complex user actions including mouse, keyboard, and touch interactions.
/**
* Actions class for building complex user interaction sequences
* Provides fluent interface for chaining multiple actions together
*/
class Actions {
/**
* Create Actions instance for specified WebDriver
* @param driver - WebDriver instance to perform actions on
*/
Actions(WebDriver driver);
/**
* Click at current mouse location
* @return Actions instance for chaining
*/
Actions click();
/**
* Click on specific element
* @param target - WebElement to click
* @return Actions instance for chaining
*/
Actions click(WebElement target);
/**
* Double-click at current mouse location
* @return Actions instance for chaining
*/
Actions doubleClick();
/**
* Double-click on specific element
* @param target - WebElement to double-click
* @return Actions instance for chaining
*/
Actions doubleClick(WebElement target);
/**
* Right-click (context click) at current mouse location
* @return Actions instance for chaining
*/
Actions contextClick();
/**
* Right-click (context click) on specific element
* @param target - WebElement to right-click
* @return Actions instance for chaining
*/
Actions contextClick(WebElement target);
/**
* Click and hold at current mouse location
* @return Actions instance for chaining
*/
Actions clickAndHold();
/**
* Click and hold on specific element
* @param target - WebElement to click and hold
* @return Actions instance for chaining
*/
Actions clickAndHold(WebElement target);
/**
* Release mouse button at current location
* @return Actions instance for chaining
*/
Actions release();
/**
* Release mouse button on specific element
* @param target - WebElement to release on
* @return Actions instance for chaining
*/
Actions release(WebElement target);
/**
* Drag from source element to target element
* @param source - Element to drag from
* @param target - Element to drag to
* @return Actions instance for chaining
*/
Actions dragAndDrop(WebElement source, WebElement target);
/**
* Drag element by specified offset
* @param source - Element to drag
* @param xOffset - Horizontal offset in pixels
* @param yOffset - Vertical offset in pixels
* @return Actions instance for chaining
*/
Actions dragAndDropBy(WebElement source, int xOffset, int yOffset);
/**
* Move mouse to specific element
* @param target - Element to move to
* @return Actions instance for chaining
*/
Actions moveToElement(WebElement target);
/**
* Move mouse to element with offset
* @param target - Element to move to
* @param xOffset - Horizontal offset from element center
* @param yOffset - Vertical offset from element center
* @return Actions instance for chaining
*/
Actions moveToElement(WebElement target, int xOffset, int yOffset);
/**
* Move mouse by specified offset from current position
* @param xOffset - Horizontal offset in pixels
* @param yOffset - Vertical offset in pixels
* @return Actions instance for chaining
*/
Actions moveByOffset(int xOffset, int yOffset);
/**
* Press and hold key
* @param key - Key to press down
* @return Actions instance for chaining
*/
Actions keyDown(Keys key);
/**
* Press and hold key on specific element
* @param target - Element to focus before key press
* @param key - Key to press down
* @return Actions instance for chaining
*/
Actions keyDown(WebElement target, Keys key);
/**
* Release key
* @param key - Key to release
* @return Actions instance for chaining
*/
Actions keyUp(Keys key);
/**
* Release key after focusing element
* @param target - Element to focus before key release
* @param key - Key to release
* @return Actions instance for chaining
*/
Actions keyUp(WebElement target, Keys key);
/**
* Send keys to currently focused element
* @param keys - Keys to send
* @return Actions instance for chaining
*/
Actions sendKeys(CharSequence... keys);
/**
* Send keys to specific element
* @param target - Element to send keys to
* @param keys - Keys to send
* @return Actions instance for chaining
*/
Actions sendKeys(WebElement target, CharSequence... keys);
/**
* Add pause to action sequence
* @param duration - Duration to pause
* @return Actions instance for chaining
*/
Actions pause(Duration duration);
/**
* Add pause using input source
* @param inputSource - Input source for pause
* @param duration - Duration to pause
* @return Actions instance for chaining
*/
Actions pause(InputSource inputSource, Duration duration);
/**
* Execute all queued actions
*/
void perform();
/**
* Build composite action without executing
* @return Action instance that can be performed later
*/
Action build();
}import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.By;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.chrome.ChromeDriver;
WebDriver driver = new ChromeDriver();
Actions actions = new Actions(driver);
try {
driver.get("https://example.com");
// Single click
WebElement button = driver.findElement(By.id("clickMe"));
actions.click(button).perform();
// Double click
WebElement doubleClickTarget = driver.findElement(By.id("doubleClickMe"));
actions.doubleClick(doubleClickTarget).perform();
// Right click (context menu)
WebElement contextTarget = driver.findElement(By.id("rightClickMe"));
actions.contextClick(contextTarget).perform();
// Click at current mouse position
actions.click().perform();
} finally {
driver.quit();
}// Move to element (hover)
WebElement menuItem = driver.findElement(By.id("menu"));
actions.moveToElement(menuItem).perform();
// Move to element with offset
WebElement canvas = driver.findElement(By.id("canvas"));
actions.moveToElement(canvas, 100, 50).perform(); // 100px right, 50px down from center
// Move by offset from current position
actions.moveByOffset(50, -25).perform(); // Move 50px right, 25px up
// Chain movements
actions.moveToElement(menuItem)
.pause(Duration.ofSeconds(1))
.moveToElement(driver.findElement(By.id("submenu")))
.click()
.perform();// Simple drag and drop
WebElement source = driver.findElement(By.id("draggable"));
WebElement target = driver.findElement(By.id("droppable"));
actions.dragAndDrop(source, target).perform();
// Drag and drop with offset
WebElement dragElement = driver.findElement(By.id("slider"));
actions.dragAndDropBy(dragElement, 100, 0).perform(); // Drag 100px to the right
// Manual drag and drop (more control)
actions.clickAndHold(source)
.moveToElement(target)
.release()
.perform();
// Complex drag with intermediate steps
actions.clickAndHold(source)
.moveByOffset(50, 0)
.pause(Duration.ofMilliseconds(500))
.moveByOffset(50, 0)
.moveToElement(target)
.release()
.perform();// Send keys to focused element
WebElement textField = driver.findElement(By.id("text"));
textField.click(); // Focus the element first
actions.sendKeys("Hello World").perform();
// Send keys to specific element
actions.sendKeys(textField, "Direct input").perform();
// Key combinations
actions.keyDown(Keys.CONTROL)
.sendKeys("a") // Ctrl+A (Select All)
.keyUp(Keys.CONTROL)
.perform();
// Multiple key combinations
actions.keyDown(Keys.CONTROL)
.keyDown(Keys.SHIFT)
.sendKeys("home") // Ctrl+Shift+Home
.keyUp(Keys.SHIFT)
.keyUp(Keys.CONTROL)
.perform();// Copy and paste
WebElement sourceField = driver.findElement(By.id("source"));
WebElement targetField = driver.findElement(By.id("target"));
// Select all and copy
actions.click(sourceField)
.keyDown(Keys.CONTROL)
.sendKeys("a")
.sendKeys("c")
.keyUp(Keys.CONTROL)
.perform();
// Click target and paste
actions.click(targetField)
.keyDown(Keys.CONTROL)
.sendKeys("v")
.keyUp(Keys.CONTROL)
.perform();
// Tab navigation
actions.sendKeys(Keys.TAB) // Move to next field
.sendKeys("Tab input")
.sendKeys(Keys.SHIFT, Keys.TAB) // Move to previous field
.perform();
// Special keys
actions.sendKeys(Keys.ENTER).perform(); // Submit form
actions.sendKeys(Keys.ESCAPE).perform(); // Close dialog
actions.sendKeys(Keys.F5).perform(); // Refresh page// Complex form interaction
WebElement form = driver.findElement(By.id("complexForm"));
WebElement field1 = form.findElement(By.name("field1"));
WebElement field2 = form.findElement(By.name("field2"));
WebElement dropdown = form.findElement(By.id("dropdown"));
WebElement submitBtn = form.findElement(By.id("submit"));
actions.click(field1)
.sendKeys("First value")
.sendKeys(Keys.TAB)
.sendKeys("Second value")
.click(dropdown)
.sendKeys(Keys.ARROW_DOWN)
.sendKeys(Keys.ARROW_DOWN)
.sendKeys(Keys.ENTER)
.click(submitBtn)
.perform();// Drawing on HTML5 canvas
WebElement canvas = driver.findElement(By.id("drawingCanvas"));
// Draw a square
actions.moveToElement(canvas, -50, -50) // Move to starting point
.clickAndHold()
.moveByOffset(100, 0) // Draw right side
.moveByOffset(0, 100) // Draw bottom side
.moveByOffset(-100, 0) // Draw left side
.moveByOffset(0, -100) // Draw top side
.release()
.perform();
// Draw with pauses for smooth animation
actions.moveToElement(canvas, 0, 0)
.clickAndHold()
.moveByOffset(10, 10).pause(Duration.ofMilliseconds(50))
.moveByOffset(10, 10).pause(Duration.ofMilliseconds(50))
.moveByOffset(10, 10).pause(Duration.ofMilliseconds(50))
.release()
.perform();// Horizontal slider
WebElement slider = driver.findElement(By.id("priceRange"));
int sliderWidth = slider.getSize().getWidth();
// Move slider to 75% position
int targetOffset = (int) (sliderWidth * 0.75) - (sliderWidth / 2);
actions.moveToElement(slider)
.clickAndHold()
.moveByOffset(targetOffset, 0)
.release()
.perform();
// Vertical slider
WebElement verticalSlider = driver.findElement(By.id("volumeSlider"));
int sliderHeight = verticalSlider.getSize().getHeight();
// Move to 25% from bottom
int verticalOffset = (sliderHeight / 2) - (int) (sliderHeight * 0.25);
actions.moveToElement(verticalSlider)
.clickAndHold()
.moveByOffset(0, verticalOffset)
.release()
.perform();// Create reusable action for login
public Action createLoginAction(WebElement usernameField, WebElement passwordField,
WebElement loginButton, String username, String password) {
return new Actions(driver)
.click(usernameField)
.sendKeys(username)
.click(passwordField)
.sendKeys(password)
.click(loginButton)
.build();
}
// Use the reusable action
Action loginAction = createLoginAction(
driver.findElement(By.id("username")),
driver.findElement(By.id("password")),
driver.findElement(By.id("login")),
"testuser",
"testpass"
);
loginAction.perform();
// Chain multiple custom actions
Action fillFormAction = new Actions(driver)
.click(driver.findElement(By.id("firstName")))
.sendKeys("John")
.sendKeys(Keys.TAB)
.sendKeys("Doe")
.build();
Action submitFormAction = new Actions(driver)
.click(driver.findElement(By.id("submit")))
.build();
// Execute in sequence
fillFormAction.perform();
Thread.sleep(1000); // Wait between actions if needed
submitFormAction.perform();// Safe action execution with error handling
public void performActionSafely(Action action, String actionDescription) {
try {
action.perform();
System.out.println("Successfully performed: " + actionDescription);
} catch (Exception e) {
System.err.println("Failed to perform " + actionDescription + ": " + e.getMessage());
// Optionally take screenshot for debugging
takeScreenshot("failed_action_" + System.currentTimeMillis() + ".png");
}
}
// Retry pattern for flaky actions
public void performActionWithRetry(Actions actions, int maxRetries) {
for (int attempt = 1; attempt <= maxRetries; attempt++) {
try {
actions.perform();
return; // Success, exit method
} catch (Exception e) {
if (attempt == maxRetries) {
throw new RuntimeException("Action failed after " + maxRetries + " attempts", e);
}
// Wait before retry
try {
Thread.sleep(1000);
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
throw new RuntimeException("Interrupted during retry", ie);
}
}
}
}// Batch actions for better performance
Actions batchActions = new Actions(driver);
// Add multiple actions to batch
WebElement form = driver.findElement(By.id("form"));
List<WebElement> fields = form.findElements(By.tagName("input"));
String[] values = {"Value1", "Value2", "Value3", "Value4"};
for (int i = 0; i < fields.size() && i < values.length; i++) {
batchActions.click(fields.get(i)).sendKeys(values[i]);
}
// Execute all actions at once
batchActions.perform();
// Use pauses strategically for timing-sensitive interactions
actions.moveToElement(dropdown)
.pause(Duration.ofMilliseconds(500)) // Wait for hover effect
.click(dropdown.findElement(By.className("option")))
.perform();Install with Tessl CLI
npx tessl i tessl/maven-org-seleniumhq-selenium--selenium-api