Composite Actions in Selenium WebDriver
Composite Actions in Selenium WebDriver are a powerful way to combine multiple mouse and keyboard interactions into a single automated action sequence. Instead of performing every interaction independently, Selenium allows testers to chain operations such as mouse movement, clicking, double-clicking, right-clicking, dragging, keyboard shortcuts, typing, holding keys, releasing keys, and pauses into one logical workflow.
Composite actions are especially useful when a real user interaction requires multiple steps to complete one business operation. For example, hovering over a menu and clicking a submenu, clicking inside a text field and using Ctrl+A before typing, holding a mouse button while moving an element, or using keyboard shortcuts together with mouse actions.
Composite Actions are implemented in Java using Selenium's Actions class from the org.openqa.selenium.interactions package. The Selenium WebDriver Actions API provides a high-level way to construct complex user interactions.
Course Resource: Selenium Training Course | Register for Course Demo
1. What Are Composite Actions?
A composite action is a sequence containing two or more user interactions that are executed together in a defined order. Selenium's Actions class allows multiple interactions to be chained before the final perform() operation executes them.
For example, the following sequence is a composite action:
moveToElement(menu)
.click(subMenu)
.perform();
Here, moving the mouse to the menu and clicking the submenu are treated as one interaction sequence.
2. Why Are Composite Actions Important?
- They automate realistic user interactions.
- They combine mouse and keyboard operations.
- They make complex workflows easier to express.
- They reduce repetitive action code.
- They support advanced browser interactions.
- They are useful for testing interactive web applications.
- They can improve readability when a business action contains several steps.
3. Selenium Actions Class
The Selenium Actions class is used to build sequences of keyboard and mouse interactions.
import org.openqa.selenium.interactions.Actions;
A basic Actions object can be created using the WebDriver instance.
Actions actions = new Actions(driver);
4. Basic Composite Action Syntax
Actions actions = new Actions(driver);
actions
.moveToElement(element)
.click()
.perform();
The methods are chained together, and perform() executes the resulting action sequence.
5. Composite Actions Flow
User Interaction
|
v
Actions Object
|
v
Build Action Sequence
|
+---- Mouse Action
|
+---- Keyboard Action
|
+---- Mouse Action
|
+---- Pause
|
v
perform()
|
v
Browser Executes Sequence
6. Important Methods of Actions Class
| Method | Purpose |
| moveToElement() | Moves the mouse pointer to an element. |
| click() | Performs a left mouse click. |
| doubleClick() | Performs a double click. |
| contextClick() | Performs a right click. |
| clickAndHold() | Presses and holds the mouse button. |
| release() | Releases the mouse button. |
| dragAndDrop() | Drags one element to another element. |
| dragAndDropBy() | Drags an element by specified coordinates. |
| keyDown() | Presses and holds a keyboard key. |
| keyUp() | Releases a keyboard key. |
| sendKeys() | Sends keyboard input. |
| pause() | Inserts a pause into the action sequence. |
| build() | Builds the action sequence explicitly. |
| perform() | Executes the action sequence. |
7. Import Statements
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.Keys;
8. Creating an Actions Object
WebDriver driver = new ChromeDriver();
Actions actions = new Actions(driver);
The Actions object uses the active WebDriver session to perform low-level user interactions.
9. Mouse and Keyboard Composite Actions
Composite actions can contain both mouse and keyboard operations.
actions
.moveToElement(searchBox)
.click()
.keyDown(Keys.CONTROL)
.sendKeys("a")
.keyUp(Keys.CONTROL)
.sendKeys("Selenium")
.perform();
This sequence moves to the search box, clicks it, selects the existing text, releases Ctrl, and enters new text.
10. Understanding perform()
perform() is used to execute the action sequence.
actions
.moveToElement(element)
.click()
.perform();
Without executing the sequence, constructing the chain alone does not complete the intended browser interaction.
11. Using build()
The build() method can be used when you want to explicitly create an Action object before executing it.
Action action = actions
.moveToElement(element)
.click()
.build();
action.perform();
For most common Selenium automation scripts, directly calling perform() is simpler.
12. Move and Click Composite Action
actions
.moveToElement(loginButton)
.click()
.perform();
This is useful when the element needs to be targeted with a mouse movement before clicking.
13. Hover and Click
WebElement menu = driver.findElement(By.id("products"));
WebElement option = driver.findElement(By.id("laptops"));
actions
.moveToElement(menu)
.pause(Duration.ofMillis(500))
.click(option)
.perform();
This pattern is commonly used for menus that display additional options after hovering.
14. Click and Type
actions
.click(searchBox)
.sendKeys("Selenium WebDriver")
.perform();
This combines clicking and typing into one action sequence.
15. Click, Select All and Type
actions
.click(searchBox)
.keyDown(Keys.CONTROL)
.sendKeys("a")
.keyUp(Keys.CONTROL)
.sendKeys("Composite Actions")
.perform();
This is useful when replacing existing input text.
16. Click and Press Enter
actions
.click(searchBox)
.sendKeys("Selenium")
.sendKeys(Keys.ENTER)
.perform();
17. Keyboard Shortcut with Mouse Action
actions
.click(textArea)
.keyDown(Keys.CONTROL)
.sendKeys("a")
.keyUp(Keys.CONTROL)
.sendKeys(Keys.BACK_SPACE)
.perform();
This demonstrates how mouse and keyboard inputs can be combined.
18. Click and Hold
actions
.clickAndHold(element)
.perform();
The mouse button remains pressed until a release action is performed.
19. Click and Hold with Move
actions
.clickAndHold(source)
.moveToElement(target)
.release()
.perform();
This pattern is useful for custom drag-and-drop controls.
20. Drag and Drop as a Composite Action
actions
.dragAndDrop(source, target)
.perform();
It represents a common multi-step interaction involving pressing, moving, and releasing the pointer.
21. Drag and Drop by Offset
actions
.dragAndDropBy(element, 200, 0)
.perform();
The element is moved relative to its current position.
22. Right Click and Keyboard Action
actions
.contextClick(element)
.sendKeys(Keys.ARROW_DOWN)
.sendKeys(Keys.ENTER)
.perform();
This can be used for custom context menus when the application supports keyboard navigation.
23. Double Click and Keyboard Action
actions
.doubleClick(element)
.sendKeys(Keys.CONTROL, "c")
.perform();
The exact behavior depends on how the target application handles selection and focus.
24. Keyboard Navigation with Tab
actions
.click(firstField)
.sendKeys("John")
.sendKeys(Keys.TAB)
.sendKeys("Doe")
.sendKeys(Keys.TAB)
.sendKeys("[email protected]")
.perform();
This is useful for testing keyboard-driven form workflows.
25. Using SHIFT in Composite Actions
actions
.keyDown(Keys.SHIFT)
.sendKeys("selenium")
.keyUp(Keys.SHIFT)
.perform();
The key is held while the text is entered and then released.
26. Using CONTROL in Composite Actions
actions
.keyDown(Keys.CONTROL)
.sendKeys("a")
.keyUp(Keys.CONTROL)
.perform();
On Windows and Linux, Ctrl is commonly used for browser and application shortcuts.
27. Using META on macOS
actions
.keyDown(Keys.META)
.sendKeys("a")
.keyUp(Keys.META)
.perform();
macOS applications commonly use the Command key for shortcuts, represented by Keys.META.
28. Why keyDown() and keyUp() Should Be Paired
When a modifier key is pressed using keyDown(), it should normally be released using keyUp().
actions
.keyDown(Keys.CONTROL)
.sendKeys("a")
.keyUp(Keys.CONTROL)
.perform();
Failing to release a modifier can cause later interactions to behave unexpectedly.
29. Combining Multiple Mouse Operations
actions
.moveToElement(menu)
.click()
.moveToElement(subMenu)
.click()
.doubleClick(item)
.perform();
This demonstrates several mouse operations inside one sequence.
30. Combining Multiple Keyboard Operations
actions
.click(input)
.sendKeys("Hello")
.sendKeys(Keys.SPACE)
.sendKeys("Selenium")
.sendKeys(Keys.ENTER)
.perform();
31. Combining Mouse and Keyboard Actions
actions
.moveToElement(input)
.click()
.keyDown(Keys.CONTROL)
.sendKeys("a")
.keyUp(Keys.CONTROL)
.sendKeys("Automation")
.sendKeys(Keys.ENTER)
.perform();
32. Pause Inside a Composite Action
The pause() method can add a controlled delay between actions.
import java.time.Duration;
actions
.moveToElement(menu)
.pause(Duration.ofMillis(500))
.click()
.perform();
Pauses should be used carefully. Explicit waits are generally better when the test needs to synchronize with application state.
33. Composite Actions vs Separate Actions
| Composite Actions | Separate Actions |
| Multiple operations are chained. | Operations are executed independently. |
| Useful for one logical interaction. | Useful when operations are unrelated. |
| Can combine mouse and keyboard inputs. | Each operation can be handled separately. |
| Provides a clear interaction sequence. | Can provide easier debugging for individual steps. |
34. Composite Actions and User Behavior
Composite actions are valuable because they can represent interactions closer to how a real user operates a web application.
Hover
↓
Open Menu
↓
Click Option
↓
Focus Input
↓
Type Data
↓
Press Enter
↓
Validate Result
35. Composite Actions with Explicit Wait
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
WebElement button = wait.until(
ExpectedConditions.elementToBeClickable(By.id("submit"))
);
actions
.moveToElement(button)
.click()
.perform();
The explicit wait handles application synchronization while the Actions class handles the user interaction.
36. Why Explicit Wait Is Better Than Arbitrary Sleep
Using a fixed delay does not guarantee that an element is ready. Explicit waits can wait for a meaningful browser condition.
WebElement element = wait.until(
ExpectedConditions.visibilityOfElementLocated(By.id("menu"))
);
37. Composite Actions with Dynamic Elements
Dynamic applications may update elements after clicks, AJAX requests, animations, or other browser events. Waiting for the required state before creating or executing an interaction helps improve test stability.
38. Composite Actions with Hover Menus
WebElement mainMenu = wait.until(
ExpectedConditions.visibilityOfElementLocated(By.id("mainMenu"))
);
WebElement subMenu = wait.until(
ExpectedConditions.visibilityOfElementLocated(By.id("subMenu"))
);
actions
.moveToElement(mainMenu)
.pause(Duration.ofMillis(300))
.moveToElement(subMenu)
.click()
.perform();
39. Composite Actions with Search
actions
.click(searchBox)
.keyDown(Keys.CONTROL)
.sendKeys("a")
.keyUp(Keys.CONTROL)
.sendKeys("Selenium WebDriver")
.sendKeys(Keys.ENTER)
.perform();
40. Composite Actions with Login Form
actions
.click(username)
.sendKeys("testuser")
.sendKeys(Keys.TAB)
.sendKeys("Password123")
.sendKeys(Keys.TAB)
.sendKeys(Keys.ENTER)
.perform();
41. Composite Actions with Registration Form
actions
.click(firstName)
.sendKeys("John")
.sendKeys(Keys.TAB)
.sendKeys("Doe")
.sendKeys(Keys.TAB)
.sendKeys("[email protected]")
.sendKeys(Keys.TAB)
.sendKeys("Password123")
.sendKeys(Keys.TAB)
.sendKeys(Keys.ENTER)
.perform();
42. Composite Actions with Modal Dialog
actions
.click(openModalButton)
.pause(Duration.ofMillis(300))
.sendKeys(Keys.ESCAPE)
.perform();
This can be useful when a web application's modal supports Escape-based closing.
43. Composite Actions with a Slider
actions
.click(slider)
.sendKeys(Keys.ARROW_RIGHT)
.sendKeys(Keys.ARROW_RIGHT)
.sendKeys(Keys.ARROW_RIGHT)
.perform();
This is useful when a slider supports keyboard-based movement.
44. Composite Actions with Contenteditable Elements
actions
.click(editor)
.sendKeys("Selenium Composite Actions")
.keyDown(Keys.CONTROL)
.sendKeys("a")
.keyUp(Keys.CONTROL)
.sendKeys("Updated Content")
.perform();
45. Composite Actions with Autocomplete
actions
.click(searchBox)
.sendKeys("Mumbai")
.pause(Duration.ofMillis(500))
.sendKeys(Keys.ARROW_DOWN)
.sendKeys(Keys.ENTER)
.perform();
The pause should be replaced by an appropriate explicit wait when the application provides a reliable condition for the suggestion list.
46. Composite Actions with Calendar Navigation
actions
.click(calendar)
.sendKeys(Keys.ARROW_RIGHT)
.sendKeys(Keys.ARROW_RIGHT)
.sendKeys(Keys.ENTER)
.perform();
47. Composite Actions for File Upload
File upload is generally handled more reliably by sending the file path directly to an input element of type file rather than attempting to automate the operating system file picker with keyboard actions.
WebElement upload = driver.findElement(By.cssSelector("input[type='file']"));
upload.sendKeys("/path/to/file.pdf");
48. Composite Actions and Alerts
JavaScript alerts should normally be handled using Selenium's Alert API rather than trying to control them with composite keyboard actions.
Alert alert = driver.switchTo().alert();
alert.accept();
49. Composite Actions and Frames
Before interacting with elements inside an iframe, switch into the appropriate frame.
driver.switchTo().frame("paymentFrame");
actions
.click(cardNumber)
.sendKeys("4111111111111111")
.perform();
driver.switchTo().defaultContent();
50. Composite Actions and Multiple Windows
Actions operate in the currently selected browser window. If an interaction must occur in another window or tab, switch to that window first.
driver.switchTo().window(windowHandle);
actions
.click(element)
.perform();
51. Composite Actions and WebElement Focus
Keyboard operations depend on focus. Clicking the required input before sending keyboard commands can make the intended target explicit.
actions
.click(input)
.sendKeys("Automation Testing")
.perform();
52. WebElement.sendKeys() vs Actions.sendKeys()
| WebElement.sendKeys() | Actions.sendKeys() |
| Primarily sends text to a specific element. | Can be part of a multi-step interaction sequence. |
| Simple for normal input. | Useful for keyboard combinations and workflows. |
| Usually easier for ordinary form fields. | Useful with mouse and keyboard combinations. |
53. Simple Input Using WebElement
username.sendKeys("testuser");
54. Complex Input Using Actions
actions
.click(username)
.keyDown(Keys.CONTROL)
.sendKeys("a")
.keyUp(Keys.CONTROL)
.sendKeys("newuser")
.perform();
55. Composite Actions for Rich Text Formatting
actions
.click(editor)
.sendKeys("Important Text")
.keyDown(Keys.CONTROL)
.sendKeys("a")
.keyUp(Keys.CONTROL)
.keyDown(Keys.CONTROL)
.sendKeys("b")
.keyUp(Keys.CONTROL)
.perform();
The exact keyboard shortcut depends on the application being tested.
56. Composite Actions with Multiple Modifier Keys
actions
.keyDown(Keys.CONTROL)
.keyDown(Keys.SHIFT)
.sendKeys("s")
.keyUp(Keys.SHIFT)
.keyUp(Keys.CONTROL)
.perform();
Modifier keys should be released in a controlled manner after the intended shortcut.
57. Composite Actions with Arrow Keys
actions
.click(dropdown)
.sendKeys(Keys.ARROW_DOWN)
.sendKeys(Keys.ARROW_DOWN)
.sendKeys(Keys.ENTER)
.perform();
58. Composite Actions with HOME and END
actions
.click(input)
.sendKeys(Keys.HOME)
.sendKeys(Keys.SHIFT, Keys.END)
.perform();
The behavior depends on the browser and the target control.
59. Composite Actions for Text Selection
actions
.click(input)
.keyDown(Keys.SHIFT)
.sendKeys(Keys.HOME)
.keyUp(Keys.SHIFT)
.perform();
60. Composite Actions with Mouse Movement
actions
.moveToElement(element)
.perform();
Mouse movement can trigger hover states, tooltips, menus, or other application behavior.
61. Moving to an Offset
actions
.moveToElement(element, 20, 10)
.perform();
The offset is relative to the target element's location.
62. Composite Actions for Tooltip Testing
actions
.moveToElement(helpIcon)
.pause(Duration.ofMillis(500))
.perform();
After the action, an explicit wait can be used to verify that the tooltip is visible.
63. Composite Actions for Menu Navigation
actions
.moveToElement(products)
.pause(Duration.ofMillis(300))
.moveToElement(category)
.click()
.perform();
64. Composite Actions for Custom Dropdowns
actions
.click(dropdown)
.sendKeys(Keys.ARROW_DOWN)
.sendKeys(Keys.ARROW_DOWN)
.sendKeys(Keys.ENTER)
.perform();
65. Composite Actions for Checkbox Workflows
actions
.click(termsCheckbox)
.sendKeys(Keys.TAB)
.sendKeys(Keys.SPACE)
.perform();
This can be useful for testing keyboard accessibility when the application supports such navigation.
66. Composite Actions for Keyboard Accessibility Testing
Composite actions can be used to automate keyboard-only workflows.
actions
.click(pageBody)
.sendKeys(Keys.TAB)
.sendKeys(Keys.TAB)
.sendKeys(Keys.ENTER)
.perform();
67. Composite Actions for Form Navigation
actions
.click(firstName)
.sendKeys("John")
.sendKeys(Keys.TAB)
.sendKeys("Doe")
.sendKeys(Keys.TAB)
.sendKeys("[email protected]")
.sendKeys(Keys.TAB)
.sendKeys(Keys.ENTER)
.perform();
68. Composite Actions for Search and Navigation
actions
.click(searchBox)
.sendKeys("Selenium")
.sendKeys(Keys.ENTER)
.perform();
69. Composite Actions for Shopping Cart Workflow
actions
.moveToElement(product)
.click(addToCart)
.pause(Duration.ofMillis(500))
.click(cartIcon)
.perform();
In a real test, application state should be synchronized using explicit waits rather than relying on fixed pauses.
70. Composite Actions for E-Commerce Filters
actions
.click(filter)
.sendKeys(Keys.ARROW_DOWN)
.sendKeys(Keys.ENTER)
.click(applyButton)
.perform();
71. Composite Actions for Dragging a Slider
actions
.clickAndHold(slider)
.moveByOffset(100, 0)
.release()
.perform();
72. Composite Actions with moveByOffset()
actions
.moveToElement(element)
.clickAndHold()
.moveByOffset(150, 0)
.release()
.perform();
This is useful when the application requires pointer movement by coordinates.
73. Composite Actions and Element Interception
If another element overlays the target, a click may fail or interact with the wrong element. Waiting for the correct state and ensuring the target is interactable can reduce such failures.
WebElement button = wait.until(
ExpectedConditions.elementToBeClickable(By.id("submit"))
);
actions.click(button).perform();
74. Composite Actions and Stale Elements
A dynamic page may replace an element after it has been located. In that situation, the previously stored WebElement reference may become stale.
WebElement button = wait.until(
ExpectedConditions.elementToBeClickable(By.id("submit"))
);
actions.click(button).perform();
If the page replaces the element, locate the current element again rather than repeatedly using an obsolete reference.
75. Common Exceptions
| Exception | Possible Cause |
| NoSuchElementException | Element could not be located. |
| StaleElementReferenceException | DOM changed after the element was located. |
| ElementNotInteractableException | Element is not currently interactable. |
| ElementClickInterceptedException | Another element is blocking the target. |
| MoveTargetOutOfBoundsException | Pointer movement target is outside the valid area. |
| TimeoutException | Required condition was not met within the wait period. |
76. Handling ElementClickInterceptedException
WebElement button = wait.until(
ExpectedConditions.elementToBeClickable(By.id("submit"))
);
actions
.moveToElement(button)
.click()
.perform();
If the application has overlays or animations, wait for those states to complete before interacting.
77. Handling StaleElementReferenceException
WebElement button = wait.until(
ExpectedConditions.elementToBeClickable(By.id("submit"))
);
actions.click(button).perform();
For dynamic pages, obtain a fresh element reference after the DOM changes.
78. Avoiding Thread.sleep()
Using arbitrary Thread.sleep() values can make tests slow and unreliable. Prefer explicit conditions whenever possible.
WebElement element = wait.until(
ExpectedConditions.visibilityOfElementLocated(By.id("result"))
);
79. Composite Actions with TestNG
import org.testng.Assert;
import org.testng.annotations.Test;
@Test
public void searchTest() {
actions
.click(searchBox)
.sendKeys("Selenium")
.sendKeys(Keys.ENTER)
.perform();
Assert.assertTrue(driver.getTitle().contains("Selenium"));
}
80. Composite Actions in Page Object Model
Composite interactions can be encapsulated inside Page Object methods so that test cases remain readable.
public class LoginPage {
private WebDriver driver;
private Actions actions;
private By username = By.id("username");
private By password = By.id("password");
public LoginPage(WebDriver driver) {
this.driver = driver;
this.actions = new Actions(driver);
}
public void enterLoginDetails(String user, String pass) {
WebElement userField = driver.findElement(username);
WebElement passField = driver.findElement(password);
actions
.click(userField)
.sendKeys(user)
.sendKeys(Keys.TAB)
.sendKeys(pass)
.perform();
}
}
81. Reusable Composite Action Utility
public class ActionUtils {
private WebDriver driver;
private Actions actions;
public ActionUtils(WebDriver driver) {
this.driver = driver;
this.actions = new Actions(driver);
}
public void hoverAndClick(WebElement element) {
actions
.moveToElement(element)
.click()
.perform();
}
public void clickAndType(WebElement element, String text) {
actions
.click(element)
.sendKeys(text)
.perform();
}
public void dragAndDrop(WebElement source, WebElement target) {
actions
.dragAndDrop(source, target)
.perform();
}
}
82. Reusable Select-All-and-Type Utility
public void replaceText(WebElement element, String text) {
actions
.click(element)
.keyDown(Keys.CONTROL)
.sendKeys("a")
.keyUp(Keys.CONTROL)
.sendKeys(text)
.perform();
}
83. Reusable Keyboard Navigation Utility
public void pressEnter(WebElement element) {
actions
.click(element)
.sendKeys(Keys.ENTER)
.perform();
}
84. Reusable Hover Utility
public void hover(WebElement element) {
actions
.moveToElement(element)
.perform();
}
85. Composite Actions in a Test Framework
A scalable automation framework can organize composite actions into layers.
Test Case
|
v
Page Object
|
v
Action Utility
|
v
Selenium Actions API
|
v
WebDriver
|
v
Browser
86. Composite Actions and Maintainability
Putting repeated interactions into reusable methods helps reduce duplication. If an interaction changes, the utility or page object can be updated instead of changing every test case.
87. Composite Actions and Readable Tests
Instead of writing many low-level interactions directly inside the test, a Page Object can expose a meaningful business-level method.
loginPage.loginUsingKeyboard("testuser", "Password123");
The underlying implementation can use a composite Actions sequence.
88. Composite Actions and Business Workflows
Complex business workflows often contain multiple UI interactions.
Open Product
↓
Hover Category
↓
Click Product
↓
Select Quantity
↓
Add to Cart
↓
Open Cart
↓
Checkout
Composite Actions can be used for the interaction-heavy portions of such workflows.
89. Composite Actions for Login Workflow
actions
.click(username)
.sendKeys("testuser")
.sendKeys(Keys.TAB)
.sendKeys("Password123")
.sendKeys(Keys.ENTER)
.perform();
90. Composite Actions for Checkout Workflow
actions
.click(addressField)
.sendKeys("Mumbai")
.sendKeys(Keys.TAB)
.sendKeys("400001")
.sendKeys(Keys.TAB)
.sendKeys(Keys.ENTER)
.perform();
91. Composite Actions for Navigation Menu
actions
.moveToElement(menu)
.pause(Duration.ofMillis(300))
.moveToElement(subMenu)
.click()
.perform();
92. Composite Actions for Multi-Step Search
actions
.click(searchBox)
.keyDown(Keys.CONTROL)
.sendKeys("a")
.keyUp(Keys.CONTROL)
.sendKeys("Selenium WebDriver")
.sendKeys(Keys.ENTER)
.perform();
93. Composite Actions for Table Interaction
WebElement row = driver.findElement(By.cssSelector("table tbody tr:first-child"));
actions
.moveToElement(row)
.click()
.perform();
For more complex table interactions, combine the action with explicit waits and appropriate element identification.
94. Composite Actions for Custom Web Components
Modern applications may contain custom controls whose interaction behavior differs from ordinary HTML elements. Composite actions can reproduce mouse and keyboard sequences required by those controls when they expose standard browser interaction behavior.
95. Composite Actions and JavaScript
JavaScript execution should not automatically replace a real user interaction. When the objective is to test actual mouse or keyboard behavior, Selenium's Actions API is generally more appropriate.
actions
.moveToElement(element)
.click()
.perform();
96. Composite Actions and Accessibility
Keyboard-based composite actions can help test workflows where users navigate controls without relying exclusively on a mouse.
actions
.click(pageBody)
.sendKeys(Keys.TAB)
.sendKeys(Keys.TAB)
.sendKeys(Keys.ENTER)
.perform();
97. Composite Actions and Cross-Browser Testing
Composite interactions should be tested across the browsers supported by the application. Browser behavior, rendering, focus handling, and application-specific event processing can affect interaction behavior.
Chrome
Firefox
Edge
|
v
Same Selenium Test
|
v
Composite Actions
|
v
Browser Compatibility Validation
98. Composite Actions with Selenium Grid
Composite Actions can be executed in remote browser sessions through Selenium Grid. The test should still use appropriate synchronization and stable locators.
Test
|
v
Selenium Grid
|
+---- Chrome
+---- Firefox
+---- Edge
|
v
Composite Action Execution
99. Composite Actions in CI/CD
Composite action tests can run as part of automated CI/CD pipelines using tools such as Jenkins or other CI platforms.
Code Commit
|
v
CI Pipeline
|
v
Build
|
v
Run Selenium Tests
|
v
Composite Interaction Tests
|
v
Reports
100. Complete Composite Actions Example
import java.time.Duration;
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.Keys;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
public class CompositeActionsExample {
public static void main(String[] args) {
WebDriver driver = new ChromeDriver();
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
Actions actions = new Actions(driver);
try {
driver.manage().window().maximize();
driver.get("https://example.com");
WebElement searchBox = wait.until(
ExpectedConditions.elementToBeClickable(By.id("search"))
);
actions
.click(searchBox)
.keyDown(Keys.CONTROL)
.sendKeys("a")
.keyUp(Keys.CONTROL)
.sendKeys("Selenium WebDriver")
.sendKeys(Keys.ENTER)
.perform();
} finally {
driver.quit();
}
}
}
101. Complete Hover and Click Example
import java.time.Duration;
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;
public class HoverClickExample {
public static void main(String[] args) {
WebDriver driver = new ChromeDriver();
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
Actions actions = new Actions(driver);
try {
driver.manage().window().maximize();
driver.get("https://example.com");
WebElement menu = wait.until(
ExpectedConditions.visibilityOfElementLocated(By.id("menu"))
);
WebElement option = wait.until(
ExpectedConditions.elementToBeClickable(By.id("option"))
);
actions
.moveToElement(menu)
.moveToElement(option)
.click()
.perform();
} finally {
driver.quit();
}
}
}
102. Complete Drag and Drop Example
WebDriver driver = new ChromeDriver();
Actions actions = new Actions(driver);
WebElement source = driver.findElement(By.id("source"));
WebElement target = driver.findElement(By.id("target"));
actions
.dragAndDrop(source, target)
.perform();
103. Composite Actions Mini Project
A practical Selenium project can combine several composite interactions into one realistic workflow.
Open Website
↓
Login
↓
Hover Products
↓
Select Category
↓
Search Product
↓
Use Keyboard Shortcut
↓
Select Product
↓
Add to Cart
↓
Open Cart
↓
Checkout
↓
Validate Result
104. Mini Project Login and Search Example
public class MiniProject {
public static void main(String[] args) {
WebDriver driver = new ChromeDriver();
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
Actions actions = new Actions(driver);
try {
driver.manage().window().maximize();
driver.get("https://example.com");
WebElement username = wait.until(
ExpectedConditions.elementToBeClickable(By.id("username"))
);
WebElement password = driver.findElement(By.id("password"));
WebElement search = driver.findElement(By.id("search"));
actions
.click(username)
.sendKeys("testuser")
.sendKeys(Keys.TAB)
.sendKeys("Password123")
.sendKeys(Keys.ENTER)
.perform();
actions
.click(search)
.sendKeys("Selenium")
.sendKeys(Keys.ENTER)
.perform();
} finally {
driver.quit();
}
}
}
105. Best Practice: Use Composite Actions for Genuine Multi-Step Interactions
Do not use the Actions API for every simple click. Use it when the interaction genuinely benefits from combining mouse and keyboard operations or when precise pointer/keyboard behavior is required.
106. Best Practice: Prefer WebElement Methods for Simple Input
username.sendKeys("testuser");
password.sendKeys("Password123");
For simple text entry, WebElement methods are often clearer than constructing an Actions chain.
107. Best Practice: Use Explicit Waits
WebElement element = wait.until(
ExpectedConditions.elementToBeClickable(By.id("button"))
);
Synchronize with application state before performing complex interactions.
108. Best Practice: Release Modifier Keys
actions
.keyDown(Keys.CONTROL)
.sendKeys("a")
.keyUp(Keys.CONTROL)
.perform();
Always ensure that modifiers such as Control, Shift, Alt, or Meta are released appropriately.
109. Best Practice: Keep Action Sequences Readable
actions
.click(searchBox)
.keyDown(Keys.CONTROL)
.sendKeys("a")
.keyUp(Keys.CONTROL)
.sendKeys("Selenium")
.sendKeys(Keys.ENTER)
.perform();
Readable chains make automation code easier to understand and maintain.
110. Best Practice: Use Meaningful Utility Methods
replaceText(searchBox, "Selenium");
hoverAndClick(productsMenu);
dragAndDrop(source, target);
Business-level methods hide low-level interaction details from test cases.
111. Best Practice: Avoid Unnecessary Pauses
Do not add pauses after every action. Use them only when a short interaction delay is genuinely required and preferably synchronize using application state instead.
112. Best Practice: Use Stable Locators
By.id("username")
By.cssSelector("[data-testid='username']")
By.xpath("//input[@name='username']")
Stable locators improve the reliability of composite interactions.
113. Best Practice: Handle Frames Before Actions
driver.switchTo().frame("paymentFrame");
actions
.click(cardNumber)
.sendKeys("4111111111111111")
.perform();
driver.switchTo().defaultContent();
114. Best Practice: Keep Tests Independent
A composite interaction should not depend on an earlier test leaving the browser in a particular state. Each test should prepare the required application state independently.
115. Best Practice: Capture Evidence for Failures
When composite interactions fail, screenshots and logs can help determine whether the issue occurred during mouse movement, clicking, keyboard input, synchronization, or application behavior.
116. Common Mistake: Forgetting perform()
A frequent mistake is creating an action chain without executing it.
actions
.click(element)
.sendKeys("Test");
Correct:
actions
.click(element)
.sendKeys("Test")
.perform();
117. Common Mistake: Not Releasing keyDown()
Incorrect:
actions
.keyDown(Keys.CONTROL)
.sendKeys("a")
.perform();
Better:
actions
.keyDown(Keys.CONTROL)
.sendKeys("a")
.keyUp(Keys.CONTROL)
.perform();
118. Common Mistake: Using Actions for Everything
Actions are not a replacement for every WebDriver operation. Use normal WebDriver and WebElement APIs when they provide a simpler and more reliable solution.
119. Common Mistake: Using JavaScript Instead of Real Interaction
Executing JavaScript to trigger a click can bypass parts of the actual user interaction. When the goal is to validate real mouse behavior, prefer Selenium Actions where appropriate.
120. Common Mistake: Ignoring Focus
Keyboard operations can go to the wrong target if the expected element does not have focus. Explicitly click or otherwise establish the intended target before sending keyboard input.
121. Common Mistake: Ignoring Dynamic Content
Menus, dropdowns, modals, and autocomplete controls can appear asynchronously. Wait for the appropriate state rather than immediately chaining actions against elements that may not yet be ready.
122. Common Mistake: Excessive Thread.sleep()
Fixed delays can make tests unnecessarily slow and still fail when the application takes longer than expected. Use explicit waits based on meaningful conditions.
123. Common Mistake: Overly Long Action Chains
A huge chain containing many unrelated business operations can become difficult to debug. Split unrelated workflows into meaningful methods or sequences.
124. Debugging Composite Action Failures
- Check whether the element exists.
- Verify the locator.
- Check whether the element is visible.
- Check whether the element is enabled.
- Verify the browser focus.
- Check overlays and popups.
- Verify the current frame.
- Verify the current browser window.
- Check whether the DOM changed.
- Use screenshots and logs.
- Check whether the action sequence requires a wait.
125. Composite Actions Debugging Flow
Action Failed
|
v
Check Locator
|
v
Check Visibility
|
v
Check Interactable State
|
v
Check Focus
|
v
Check Frame/Window
|
v
Check Dynamic DOM
|
v
Check Wait
|
v
Execute Again
126. Composite Actions Interview Question
Q1. What are Composite Actions in Selenium?
Composite Actions are combinations of multiple mouse and keyboard interactions constructed as a sequence using Selenium's Actions API and executed together using perform().
127. Interview Question: Which Class Is Used?
Q2. Which class is used for composite mouse and keyboard actions in Selenium Java?
The org.openqa.selenium.interactions.Actions class is commonly used to create such interaction sequences.
128. Interview Question: What Does perform() Do?
Q3. What is the purpose of perform()?
perform() executes the currently constructed interaction sequence.
129. Interview Question: What Is build()?
Q4. What is the purpose of build()?
build() can explicitly construct the current action sequence as an Action object, which can then be executed using perform().
130. Interview Question: Can Mouse and Keyboard Actions Be Combined?
Q5. Can Selenium combine mouse and keyboard operations?
Yes. The Actions API can combine pointer and keyboard operations in a single sequence.
131. Interview Question: What Is keyDown()?
Q6. What does keyDown() do?
It presses and holds a keyboard key during the action sequence until the corresponding keyUp() operation releases it.
132. Interview Question: Why Use keyUp()?
Q7. Why should keyUp() be used after keyDown()?
keyUp() releases the previously pressed key or modifier and helps prevent the modifier from unintentionally affecting later interactions.
133. Interview Question: How Do You Perform Drag and Drop?
Q8. How can drag and drop be performed?
actions
.dragAndDrop(source, target)
.perform();
134. Interview Question: How Do You Combine Hover and Click?
Q9. How do you hover over an element and then click another element?
actions
.moveToElement(menu)
.moveToElement(subMenu)
.click()
.perform();
135. Interview Question: How Do You Select All Text?
Q10. How do you select all text using Actions?
actions
.click(input)
.keyDown(Keys.CONTROL)
.sendKeys("a")
.keyUp(Keys.CONTROL)
.perform();
136. Interview Question: Actions vs WebElement Methods
Q11. When should Actions be preferred over WebElement methods?
Actions are particularly useful for complex mouse and keyboard sequences, hover interactions, drag-and-drop, modifier-key combinations, and workflows where multiple low-level interactions form one user operation.
137. Interview Question: Are Composite Actions Useful for Accessibility Testing?
Q12. Can composite actions be used for accessibility testing?
Yes. Keyboard-based action sequences can help automate workflows that depend on Tab, Enter, Space, arrow keys, Escape, and keyboard shortcuts.
138. Interview Question: Is Thread.sleep() Required?
Q13. Is Thread.sleep() required when using Actions?
No. Synchronization should normally be handled using explicit waits and application conditions. A controlled pause can be used when it is specifically required by the interaction.
139. Interview Question: Can Actions Work Inside an iframe?
Q14. Can Actions interact with iframe content?
Yes, but the driver must first switch into the appropriate iframe before locating and interacting with its elements.
140. Interview Question: Can Actions Handle Browser Alerts?
Q15. Should Actions be used for browser alerts?
Browser alerts should normally be handled with Selenium's Alert API because alerts are browser-level dialogs rather than ordinary page elements.
141. Quick Revision
| Concept | Key Point |
| Actions | Builds complex user interactions. |
| Composite Action | Combines multiple interactions into one sequence. |
| perform() | Executes the sequence. |
| build() | Explicitly creates an Action object. |
| moveToElement() | Moves pointer to an element. |
| click() | Performs a left click. |
| doubleClick() | Performs a double click. |
| contextClick() | Performs a right click. |
| clickAndHold() | Presses and holds the pointer button. |
| release() | Releases the pointer button. |
| dragAndDrop() | Moves an element from source to target. |
| keyDown() | Presses and holds a keyboard key. |
| keyUp() | Releases a keyboard key. |
| sendKeys() | Sends keyboard input. |
| pause() | Adds a controlled pause. |
142. Practical Checklist
- Import the Actions class.
- Create an Actions object using the WebDriver.
- Locate the required elements.
- Wait for dynamic elements when necessary.
- Build the required interaction sequence.
- Use keyDown() and keyUp() carefully.
- Use moveToElement() for hover interactions.
- Use clickAndHold() and release() for custom drag workflows.
- Use dragAndDrop() for standard drag-and-drop scenarios.
- Call perform() to execute the sequence.
- Use Page Objects for reusable interactions.
- Avoid unnecessary Thread.sleep().
- Test complex interactions across supported browsers.
143. Composite Actions Best Practices Summary
- Use Actions for genuinely complex interactions.
- Keep action chains readable.
- Prefer explicit waits for synchronization.
- Release modifier keys after using them.
- Use stable locators.
- Handle frames and windows before interaction.
- Do not use JavaScript as an automatic replacement for real user actions.
- Encapsulate repeated action sequences in reusable methods.
- Use Page Object Model for maintainable automation frameworks.
- Capture logs and screenshots when complex interactions fail.
- Keep unrelated workflows in separate methods.
144. Real-World Applications of Composite Actions
| Application | Composite Interaction |
| E-Commerce | Hover menu, select product, drag slider, checkout. |
| Banking | Keyboard navigation and secure form interactions. |
| CRM | Search, autocomplete, dropdown and keyboard workflows. |
| Admin Panels | Menus, filters, tables and drag-and-drop controls. |
| Content Editors | Typing, selecting text and keyboard formatting. |
| Project Management | Drag-and-drop tasks between columns. |
| Booking Systems | Calendar navigation and form interaction. |
| Accessibility Testing | Keyboard-only navigation and activation. |
145. Overall Composite Actions Architecture
Selenium Test
|
v
Page Object Layer
|
v
Action Utility Layer
|
v
Actions API
|
+-----------+-----------+
| |
v v
Pointer Input Keyboard Input
| |
+-----------+-----------+
|
v
W3C WebDriver
|
v
Browser
146. Final Example of a Composite Interaction
Actions actions = new Actions(driver);
actions
.moveToElement(menu)
.pause(Duration.ofMillis(300))
.click()
.sendKeys(Keys.TAB)
.sendKeys(Keys.ENTER)
.perform();
This example demonstrates how mouse movement, clicking, pausing, and keyboard operations can be combined into a single interaction sequence.
147. Conclusion
Composite Actions are an important part of Selenium WebDriver automation when applications require realistic multi-step mouse and keyboard interactions. The Selenium Actions API allows testers to combine operations such as hover, click, double-click, right-click, drag-and-drop, keyboard shortcuts, text entry, key holding, and pointer movement into structured sequences.
For reliable automation, Composite Actions should be combined with stable locators, explicit waits, Page Object Model design, reusable utilities, proper frame and window handling, and appropriate error handling. Simple operations should remain simple, while genuinely complex user workflows can be represented using readable action chains.
Recommended Selenium Learning: Learn Selenium Training | Register for Course Demo