You’re experiencing a common issue with Katalon Studio’s WebUI Drag and Drop keywords: they fail across different screen resolutions because they rely on absolute pixel coordinates or fixed element positioning that changes when screen size varies.
Root Causes:
dragAndDropByOffset() uses fixed pixel offsets (e.g., 200, 400) that don’t scale with different resolutions
dragAndDropToObject() depends on element positioning that shifts with viewport changes
- Elements may be off-screen or in different positions on different resolutions, causing the action to target the wrong location
Recommended Solutions
Solution 1: Use dragAndDropToObject() Instead of dragAndDropByOffset() (Best Practice)
The dragAndDropToObject() keyword is more reliable across resolutions because it targets element-to-element rather than fixed coordinates:
import static com.kms.katalon.core.testobject.ObjectRepository.findTestObject
import com.kms.katalon.core.webui.keyword.WebUiBuiltInKeywords as WebUI
WebUI.openBrowser('https://jqueryui.com/droppable/')
// Drag source element to destination element (resolution-independent)
WebUI.dragAndDropToObject(
findTestObject('Page_Droppable/div_draggable'),
findTestObject('Page_Droppable/div_droppable')
)
WebUI.closeBrowser()
Why this works: Element-to-element dragging automatically adjusts to wherever the elements are positioned, regardless of screen resolution.
Solution 2: Ensure Elements Are Visible Before Dragging
Set a consistent viewport size and verify element visibility:
import com.kms.katalon.core.webui.keyword.WebUiBuiltInKeywords as WebUI
WebUI.openBrowser('https://example.com')
// Set consistent viewport size
WebUI.setViewPortSize(1920, 1080)
// Scroll element into view before dragging
WebUI.scrollToElement(findTestObject('Page_Example/div_draggable'), 5)
// Verify element is visible
WebUI.verifyElementVisible(findTestObject('Page_Example/div_draggable'))
// Now perform drag and drop
WebUI.dragAndDropToObject(
findTestObject('Page_Example/div_draggable'),
findTestObject('Page_Example/div_droppable')
)
WebUI.closeBrowser()
Solution 3: Use JavaScript-Based Drag and Drop (For HTML5 Elements)
For HTML5 drag-and-drop implementations, use a custom keyword that simulates drag events via JavaScript:
package html5.dnd
import org.openqa.selenium.JavascriptExecutor
import org.openqa.selenium.WebDriver
import org.openqa.selenium.WebElement
import com.kms.katalon.core.annotation.Keyword
import com.kms.katalon.core.testobject.TestObject
import com.kms.katalon.core.webui.driver.DriverFactory
import com.kms.katalon.core.webui.keyword.WebUiBuiltInKeywords
public class DragAndDropHelper {
private static String getJsDndHelper() {
return '''
function simulateDragDrop(sourceNode, destinationNode) {
var EVENT_TYPES = {
DRAG_END: 'dragend',
DRAG_START: 'dragstart',
DROP: 'drop'
};
function createCustomEvent(type) {
var event = new CustomEvent("CustomEvent");
event.initCustomEvent(type, true, true, null);
event.dataTransfer = {
data: {},
setData: function(type, val) {
this.data[type] = val;
},
getData: function(type) {
return this.data[type];
}
};
return event;
}
function dispatchEvent(node, type, event) {
if (node.dispatchEvent) {
return node.dispatchEvent(event);
}
if (node.fireEvent) {
return node.fireEvent("on" + type, event);
}
}
var event = createCustomEvent(EVENT_TYPES.DRAG_START);
dispatchEvent(sourceNode, EVENT_TYPES.DRAG_START, event);
var dropEvent = createCustomEvent(EVENT_TYPES.DROP);
dropEvent.dataTransfer = event.dataTransfer;
dispatchEvent(destinationNode, EVENT_TYPES.DROP, dropEvent);
var dragEndEvent = createCustomEvent(EVENT_TYPES.DRAG_END);
dragEndEvent.dataTransfer = event.dataTransfer;
dispatchEvent(sourceNode, EVENT_TYPES.DRAG_END, dragEndEvent);
}
''';
}
@Keyword
def dragAndDrop(TestObject sourceObject, TestObject destinationObject) {
WebElement sourceElement = WebUiBuiltInKeywords.findWebElement(sourceObject)
WebElement destinationElement = WebUiBuiltInKeywords.findWebElement(destinationObject)
WebDriver webDriver = DriverFactory.getWebDriver()
((JavascriptExecutor) webDriver).executeScript(
getJsDndHelper() + "simulateDragDrop(arguments[0], arguments[1]);",
sourceElement, destinationElement
)
}
}
Then use it in your test:
CustomKeywords.'html5.dnd.DragAndDropHelper.dragAndDrop'(
findTestObject('Page_Example/img_draggable'),
findTestObject('Page_Example/div_droppable')
)
Solution 4: Calculate Relative Offsets Dynamically
If you must use dragAndDropByOffset(), calculate offsets based on element size:
import org.openqa.selenium.WebElement
import com.kms.katalon.core.webui.keyword.WebUiBuiltInKeywords as WebUI
import com.kms.katalon.core.webui.common.WebUiCommonHelper
WebElement sourceElement = WebUiCommonHelper.findWebElement(findTestObject('Page_Example/div_draggable'), 10)
WebElement destElement = WebUiCommonHelper.findWebElement(findTestObject('Page_Example/div_droppable'), 10)
// Calculate relative offset based on element positions
int sourceX = sourceElement.getLocation().getX()
int sourceY = sourceElement.getLocation().getY()
int destX = destElement.getLocation().getX()
int destY = destElement.getLocation().getY()
int xOffset = destX - sourceX
int yOffset = destY - sourceY
// Use calculated offset
WebUI.dragAndDropByOffset(findTestObject('Page_Example/div_draggable'), xOffset, yOffset)
Key Considerations
| Approach |
Pros |
Cons |
| dragAndDropToObject() |
Resolution-independent, reliable |
Requires both elements to be captured |
| JavaScript-based |
Works for HTML5, very reliable |
Requires custom keyword setup |
| Dynamic offsets |
Flexible |
More complex code, slower execution |
| dragAndDropByOffset() |
Simple |
Resolution-dependent, unreliable |
References