What is the method to emulate drag-and-drop operations using Puppeteer?

I am utilizing React-DnD for drag-and-drop functionality in my app and need to perform end-to-end tests.

Specifically, I aim to drag an item to a designated location. What steps should I take to achieve this?

Currently, my script includes the following:

//test-script.js
const pointer = page.mouse;
await pointer.down();
await pointer.move(150, 25);
await page.waitForTimeout(400);

While this code effectively selects the item, the drag action fails to execute. What adjustments are necessary for proper implementation?

To effectively simulate drag-and-drop operations using Puppeteer, especially when working with libraries like React-DnD, you'll need to perform a series of coordinated mouse interactions. This typically involves clicking and holding on the draggable element, moving it to the desired drop location, and then releasing the mouse button. Below is a more comprehensive approach to achieve this:

//test-script.js
const pointer = page.mouse;

// Select the element you want to drag
await page.waitForSelector('.draggable-element', { visible: true });
const draggableElement = await page.$('.draggable-element');
const boundingBox = await draggableElement.boundingBox();

// Calculate the start position (center of the element)
const startX = boundingBox.x + boundingBox.width / 2;
const startY = boundingBox.y + boundingBox.height / 2;

// Move the mouse to the start position and press down
await pointer.move(startX, startY);
await pointer.down();

// Define the target position for dragging
const targetX = startX + 150; // Adjust as needed
const targetY = startY + 25;  

// Perform the drag by moving to the target position
await pointer.move(targetX, targetY, { steps: 10 });

// Release the mouse button
await pointer.up();

// Wait for the potential drop effect to complete
await page.waitForTimeout(500);

Here's the step-by-step breakdown of the code:

  1. Wait for the Draggable Element: Makes sure the element is visible and ready for interaction.
  2. Calculate Start Position: Centers the mouse on the draggable element, essential for a precise drag operation.
  3. Initiate Dragging: Starts the drag by moving the mouse to the element's center and pressing down.
  4. Define Target Position: Specifies where to drag the item. Adjust targetX and targetY according to your layout.
  5. Execute Movement: Gradually moves the mouse to the desired drop location to emulate a realistic drag action.
  6. Complete the Drag: Releases the mouse button, completing the drop action.

This sequence ensures a smooth and effective drag-and-drop operation by mimicking natural user interactions, thus helping you perform thorough end-to-end testing with Puppeteer.

To properly emulate drag-and-drop actions using Puppeteer, especially with React-DnD, follow the steps to coordinate mouse actions effectively. Your current script partially initiates the drag action but needs refinement to complete the drag-and-drop operation.

// Improved drag-and-drop script
const pointer = page.mouse;

// Ensure draggable element is ready
await page.waitForSelector('.draggable-element', { visible: true });
const elementHandle = await page.$('.draggable-element');
const boundingBox = await elementHandle.boundingBox();

// Calculate the start position
const startX = boundingBox.x + boundingBox.width / 2;
const startY = boundingBox.y + boundingBox.height / 2;

// Perform mouse actions
await pointer.move(startX, startY);
await pointer.down();

// Determine target position for the drop
const targetX = startX + 150; // Adjust based on needed final location
const targetY = startY + 25;

// Drag to the target location
await pointer.move(targetX, targetY, { steps: 10 });
await pointer.up();

// Allow any drop animations to complete
await page.waitForTimeout(600);

Here's a quick breakdown:

  • Ensure visibility: This makes sure the drag element is visible for interaction.
  • Start with precision: Move the mouse to the element's center before beginning to drag.
  • Simulate real drag: Use steps to smooth out the dragging motion.
  • Wait for completion: Give a small delay for any drop effect or animation to finish.

This method effectively simulates a real user's interaction, ensuring your tests mirror actual use-cases.