Many web applications use JavaScript (onmouseleave events) or strict CSS :hover states. When Katalon finishes the WebUI.mouseOver action, it prepares to execute the next command. During that microsecond transition, the browser often registers that the cursor has “left” the element, triggering the menu to close immediately before the WebUI.click command can locate and target the sub-menu item.
The Solution
To resolve this reliably, we need to bypass the native mouse-move sequence or force the hover state to persist. We can achieve this using two reliable methods:
-
The Safe Approach (Built-in Keywords): Use WebUI.clickOffset or explicit WebUI.waitForElementPresent loops.
-
The Robust Architect Approach (JavaScript/Custom Keyword): Use JavaScript via Katalon’s WebUI.executeJavaScript to dispatch a native mouse hover event directly to the browser DOM, or trigger the click directly on the hidden element if it’s already in the DOM structure.
Custom Keyword Solution
Instead of relying on unstable native mouse movements for every dropdown, we can create a Custom Keyword that uses JavaScript to trigger a hover event, waits for the element to be clickable, and then executes the click smoothly.
Step 1: Create the Custom Keyword
Create a new Keyword package (e.g., com.helper.menu) and paste the following code:
Groovy
package com.helper.menu
import com.kms.katalon.core.annotation.Keyword
import com.kms.katalon.core.webui.keyword.WebUiBuiltInKeywords as WebUI
import com.kms.katalon.core.testobject.TestObject
import org.openqa.selenium.WebElement
import com.kms.katalon.core.webui.common.WebUiCommonHelper
public class MenuHoverHelper {
/**
* Hovers over a parent menu using JavaScript and securely clicks the child sub-menu item.
* * @param parentMenu The TestObject of the main navigation link/button
* @param childItem The TestObject of the hidden/dropdown sub-menu item
*/
@Keyword
def hoverAndClickSubMenu(TestObject parentMenu, TestObject childItem) {
// Find the elements safely
WebElement parentElement = WebUiCommonHelper.findWebElement(parentMenu, 10)
// Use JavaScript to trigger a mouseover event that persists in the browser
String javaScript = "var evObj = document.createEvent('MouseEvents');" +
"evObj.initMouseEvent('mouseover', true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);" +
"arguments[0].dispatchEvent(evObj);"
WebUI.executeJavaScript(javaScript, Arrays.asList(parentElement))
// Wait for the sub-menu item to become interactive
WebUI.waitForElementVisible(childItem, 5)
WebUI.waitForElementClickable(childItem, 5)
// Click the sub-menu item
WebUI.click(childItem)
}
}
Step 2: How to use it in your Test Case
Script View:
Groovy
// Call your custom keyword instead of standard mouseOver
CustomKeywords.'com.helper.menu.MenuHoverHelper.hoverAndClickSubMenu'(
findTestObject('Object Repository/Main_Menu_Products'),
findTestObject('Object Repository/Sub_Menu_CloudHosting')
)
Manual View:
-
Add a new step to your test case and select Custom Keyword.
-
Select hoverAndClickSubMenu.
-
Pass your Parent Menu object as the first argument and your Sub Menu Item object as the second argument.
This architectural approach removes the timing dependency of physical cursor simulation, making your test suites significantly faster and highly resilient against UI changes.