</>

Technology

Playwright

Difficulty

Intermediate

Interview Question

How do you handle drag and drop in Playwright?

Answer

Drag and Drop in Playwright

Method 1 — locator.dragTo() (Simplest)

TypeScript
// Drag source element onto target element
await page.locator('#draggable-item').dragTo(page.locator('#drop-zone'));

// Drag a card to a different column (Kanban board)
await page.locator('.card[data-id="task-1"]').dragTo(
  page.locator('.column[data-status="done"]')
);

Method 2 — dragTo with Options

TypeScript
await page.locator('#source').dragTo(page.locator('#target'), {
  sourcePosition: { x: 10, y: 10 }, // Start from this offset within source
  targetPosition: { x: 50, y: 20 }, // Drop at this offset within target
  force: true, // Bypass actionability checks
});

Method 3 — Manual Mouse Events (For Complex UI)

TypeScript
// More control over the drag path
const source = page.locator('#item-to-drag');
const target = page.locator('#drop-target');

// Get bounding boxes
const sourceBox = await source.boundingBox();
const targetBox = await target.boundingBox();

if (sourceBox && targetBox) {
  // Move to source center
  await page.mouse.move(
    sourceBox.x + sourceBox.width / 2,
    sourceBox.y + sourceBox.height / 2
  );
  await page.mouse.down();

  // Slowly drag to target (important for smooth DnD libraries)
  await page.mouse.move(
    targetBox.x + targetBox.width / 2,
    targetBox.y + targetBox.height / 2,
    { steps: 10 } // Move in 10 steps for smooth animation
  );

  await page.mouse.up();
}

Method 4 — DataTransfer via evaluate() (HTML5 DnD)

TypeScript
// For HTML5 drag events
await page.locator('#source').dispatchEvent('dragstart');
await page.locator('#target').dispatchEvent('drop');
await page.locator('#source').dispatchEvent('dragend');

Full Example — Kanban Board

TypeScript
import { test, expect } from '@playwright/test';

test('drag task from Todo to Done', async ({ page }) => {
  await page.goto('/kanban');

  const task = page.locator('.task-card').filter({ hasText: 'Write tests' });
  const doneColumn = page.locator('.kanban-column[data-status="done"]');

  // Verify initial state
  await expect(task).toBeVisible();

  // Drag the task to Done column
  await task.dragTo(doneColumn);

  // Verify task moved to Done column
  await expect(doneColumn.locator('.task-card').filter({ hasText: 'Write tests' }))
    .toBeVisible();
});

Sortable List Example

TypeScript
test('reorder list items via drag', async ({ page }) => {
  await page.goto('/sortable-list');

  const firstItem  = page.locator('.sortable-item').nth(0);
  const thirdItem  = page.locator('.sortable-item').nth(2);

  // Move first item to third position
  await firstItem.dragTo(thirdItem);

  // Verify new order
  await expect(page.locator('.sortable-item').nth(0)).toHaveText('Item 2');
});

Follow AutomateQA

Related Topics