javascriptdrag-and-dropplaywright

Why aren't these elements dragging and dropping as expected?


I am using Playwright and trying to drag & drop the list at this site into the right order. These locators work as expected, and the drag & drop does work every so often. I have tried dragTo(), a combination of mouse up, down, and hover, and a lot of different selectors.

Nothing works consistently.

// launch browser and open a new page
const { context } = await launch();
const page = await context.newPage();

// go to sortable list site
await page.goto('https://qaplayground.dev/apps/sortable-list/');

// order list
const correctOrder = [
  'Jeff Bezos',
  'Bill Gates',
  'Warren Buffett',
  'Bernard Arnault',
  'Carlos Slim Helu',
  'Amancio Ortega',
  'Larry Ellison',
  'Mark Zuckerberg',
  'Michael Bloomberg',
  'Larry Page'
];

async function swapItemToIndex(textIndex, listIndex) {
  const correctItem = `div.draggable:has-text('${correctOrder[textIndex]}')`;
  const targetItem = `li[data-index="${listIndex}"]`;
  await page.dragAndDrop(correctItem, targetItem);
}

await swapItemToIndex(0, 0);
await swapItemToIndex(1, 1);

// the elements are not ordered as expected

Solution

  • There is a solution linked to the test, click View Test Suite (has a Playwright icon on the left).

    The sample solution indicates that the main issue is that some items are not visible when the drag-drop action is taken, and it uses nested loops and calculates distances, etc.

    I think it can be simplified by setting the viewport big enough to see all the elements.

    This is my version of the test using your fixture array and function

    test.use({
      viewport: { width: 1600, height: 1200 },
    })
    
    test.describe("Sortable List", () => {
      test("Should reorder the list to match the correct order", async ({ page }) => {
        await page.goto('https://qaplayground.dev/apps/sortable-list/');
    
        const correctOrder = [
          'Jeff Bezos',
          // ...truncated here for readability
        ];
    
        async function swapItemToIndex(text, index) {
          const currentItem = `div.draggable :has-text("${text}")`;
          const targetItem = `li[data-index="${index}"]`;
          await page.dragAndDrop(currentItem, targetItem);
          // confirm the step
          await expect(page.locator('li').nth(index)).toContainText(text)
        }
    
        for (const [index, name] of correctOrder.entries()) {
          await swapItemToIndex(name, index)
        }
    
        // confirm the list is all green
        await page.locator("#check").click(); 
        for (const li of await page.locator(".person-name").all())
          await expect(li).toHaveCSS("color", "rgb(58, 227, 116)");
        }
      });
    });
    

    enter image description here