Draggable actions
A draggable element can be selected by the user with a mouse, dragged to a droppable element, and dropped by releasing the mouse button.
Draggable element declaration
A draggable element must include draggable in its type property. In this example, one element is just draggable, but usually an element is both clickable and draggable because a user needs to click before they can drag.
1{
2 "elements": [
3 {
4 "name": "onlyDraggable",
5 "type": ["draggable"],
6 "selector": {
7 "css": ".drag-me"
8 },
9 "public": true
10 },
11 {
12 "name": "myDraggable",
13 "type": ["clickable", "draggable"],
14 "selector": {
15 "css": ".drag-me-too"
16 },
17 "public": true
18 }
19 ]
20}DragAndDrop API
The draggable type exposes the following API for an element:
dragAndDrop(target: Element, hold: number)clicks and drags an element to the location of the target element, then drops. The target element is provided as a parameter and doesn’t have to be draggable.
A second optional parameter defines a hold duration in seconds that is applied after the click and before the drag. This hold duration can be useful to simulate a real user in some cases.
Usage in a JavaScript test:
1const source = await pageObject.getMyDraggable();
2const target = await pageObject.getDropTarget();
3// drag and drop without hold
4await source.dragAndDrop(target);Usage in a Java test:
1Draggable source = pageObject.getMyDraggable();
2BasicElement target = pageObject.getDropTarget();
3// drag and drop with 3 sec hold
4source.dragAndDrop(target, 3);dragAndDropByOffset(xOffset: number, yOffset: number, hold: number)drops an element using coordinates relative to the current location of the element. It has an optional parameter for hold duration in seconds.
Usage in a JavaScript test:
1const source = await pageObject.getMyDraggable();
2// drag and drop with 3 sec hold
3await source.dragAndDropByOffset(100, 100, 3);Usage in a Java test:
1Draggable source = pageObject.getMyDraggable();
2// drag and drop without hold
3source.dragAndDropByOffset(100, 100);Compose dragAndDrop
It’s a good practice to compose a UI interaction as a public method inside a page object. Here are some examples of how to compose dragAndDrop and dragAndDropByOffset and how to provide a target element as a parameter.
Drop at a known target element
The most common use case is to drop an element at a known target element location.
To do that, we pass elementReference to a known element as an argument:
1{
2 "elements": [
3 {
4 "name": "myDraggable",
5 "type": ["draggable"],
6 "selector": { "css": ".foo" }
7 },
8 {
9 "name": "dropTarget",
10 "selector": { "css": ".moo" }
11 }
12 ],
13 "methods": [
14 {
15 "name": "dragAndDropAtTarget",
16 "compose": [
17 {
18 "element": "myDraggable",
19 "apply": "dragAndDrop",
20 "args": [
21 {
22 "type": "elementReference",
23 "value": "dropTarget"
24 }
25 ]
26 }
27 ]
28 }
29 ]
30}The generated method declarations have no parameters because the target element is referenced inside the statement of the dragAndDropAtTarget method.
Generated JavaScript method declaration:
1dragAndDropAtTarget(): Promise<unknown>;Generated Java method declaration:
1public void dragAndDropAtTarget();Drop at a known target element with hardcoded arguments
It’s possible that the target element needs arguments for the selector or filter. Those arguments can be hardcoded in a compose statement. This example passes a hardcoded myClass value to the dropTarget in the dragAndDropAtTarget method.
1{
2 "elements": [
3 {
4 "name": "myDraggable",
5 "type": ["draggable"],
6 "selector": { "css": ".foo" }
7 },
8 {
9 "name": "dropTarget",
10 "selector": {
11 "css": "target[class='%s']",
12 "args": [
13 {
14 "name": "classStr",
15 "type": "string"
16 }
17 ]
18 }
19 }
20 ],
21 "methods": [
22 {
23 "name": "dragAndDropAtTarget",
24 "compose": [
25 {
26 "element": "myDraggable",
27 "apply": "dragAndDrop",
28 "args": [
29 {
30 "type": "elementReference",
31 "value": "dropTarget",
32 "args": [{ "value": "myClass" }]
33 }
34 ]
35 }
36 ]
37 }
38 ]
39}If we omitted the "value" : "myClass" hardcoded value for the dropTarget element, it would be inferred and added to the method parameters.
JavaScript example:
1dragAndDropAtTarget(classStr: string): Promise<unknown>;Java example:
1public void dragAndDropAtTarget(String classStr);Drop by offset inside a frame
It’s always more reliable to dragAndDrop with a target element as shown in the previous section. However, that’s not possible if the target element is inside a frame. Here’s an example for Java:
1// get source element coordinates
2ElementRectangle source = sourceElement.getRect();
3
4// enter frame and get target coordinates
5MyPageObject targetPageObjectInsideFrame = utam.enterFrameAndLoad(frameElement, MyPageObject.class);
6ElementRectangle target = targetPageObjectInsideFrame.getTargetElement().getRect();
7utam.exitFrame();
8
9// offset is a difference between element centers
10int xOffset = (target.getX() + target.getWidth()/2) - (source.getX() + source.getWidth()/2);
11int yOffset = (target.getY() + target.getHeight()/2) - (source.getY() + source.getHeight()/2);
12
13// drag and drop with a 5 second pause
14source.dragAndDropByOffset(xOffset, yOffset, 5);We don’t show JavaScript code here but it’s similar and uses the same methods.