Drag and drop
Drag one element onto another with dragTo, and fall back to low-level mouse steps when needed.
dragTo() is a locator action: it drags the source element and drops it on a target locator. It handles the press, move, and release for you, and both ends are re-resolved before the drag runs.
Drag a source onto a target
Find the source and the target as locators, then call dragTo() on the source with the target as its argument.
$page->goto('https://app.example.test/board');
$card = $page->getByRole('listitem', ['name' => 'Write the changelog']);
$done = $page->getByRole('list', ['name' => 'Done']);
$card->dragTo($done);
dragTo() waits for the source to be actionable, presses on it, moves to the target, and releases. Assert the result afterwards, such as the card now appearing in the target column.
Control the drag with options
The options array tunes where the drag starts and ends and how it moves. sourcePosition and targetPosition set the pick-up and drop points relative to each element. steps splits the move into intermediate mouse events, which some drag libraries need to register the drag.
$card->dragTo($done, [
'sourcePosition' => ['x' => 10, 'y' => 10],
'targetPosition' => ['x' => 40, 'y' => 20],
'steps' => 10,
]);
Options go in an array. Available keys include sourcePosition, targetPosition, steps, force, and timeout.
Fall back to low-level mouse steps
Some interfaces track pointer movement so closely that a single drag does not trigger their handlers. When dragTo() does not register, drive the mouse yourself with known coordinates.
$mouse = $page->mouse();
$source = $card->boundingBox();
$target = $done->boundingBox();
if (null === $source || null === $target) {
throw new RuntimeException('Drag source and target must be visible');
}
$mouse->move(
$source['x'] + $source['width'] / 2,
$source['y'] + $source['height'] / 2,
);
$mouse->down();
$mouse->move(
$target['x'] + $target['width'] / 2,
$target['y'] + $target['height'] / 2,
['steps' => 10],
);
$mouse->up();
boundingBox() measures the visible source and target. Move to their centers, press with down(), move in several steps so the page sees a real drag, then release with up(). Prefer dragTo() first; use this only when the component ignores it.
Pitfalls
- Do not look for a
dragAndDrop()method on the page; the drag lives on the source locator asdragTo(). - A drag that appears to do nothing often needs intermediate
steps. Native HTML5 drag-and-drop and many JavaScript libraries only start after several move events. - Assert the outcome the app shows after the drop, not that the drag ran.
Expected result
The dragged item appears in the target location, order, or status that the product promises. Assert that visible state after the drag, such as the card appearing in the "Done" column.