Как смоделировать действие перетаскивания в кукловоде?

У меня в приложении есть React-DnD (Drag and drop). Хочу протестировать E2E.

Я хочу смоделировать перетаскивание определенного элемента в определенное место. Как мне это сделать?

Что у меня есть:

//test.js
const mouse = page.mouse;
await mouse.down();
await mouse.move(126, 19);
await page.waitFor(400);

Используя этот код, выбор сделан, но перетаскивание не работает. Как мне это реализовать?

вы ищете что-то подобное github.com/GoogleChrome/puppeteer/issues/1366

user93 11.04.2018 13:48

но у меня это не работает.

Khushi 12.04.2018 05:30

Вы пробовали этот pastebin.com/2rttzMW1?

user93 12.04.2018 08:15

да. но это также не решило мою проблему

Khushi 12.04.2018 08:45

@Khushi есть новости по этому поводу? удалось ли решить вопрос?

florin 20.01.2019 17:36

Посетите мой ответ на следующий вопрос: Как имитировать действие Drag-Drop в кукольнике

Akram Alhinnawi 10.02.2021 13:49
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
18
6
11 161
3

Ответы 3

Следующий метод позволит вам смоделировать действие перетаскивания в Puppeteer:

const example = await page.$('#example');
const bounding_box = await example.boundingBox();

await page.mouse.move(bounding_box.x + bounding_box.width / 2, bounding_box.y + bounding_box.height / 2);
await page.mouse.down();
await page.mouse.move(126, 19);
await page.mouse.up();

Вот фрагмент, который я использую для перетаскивания в кукольнике:

//This assumes only one element will be found for selectors you provide, otherwise there's ambiguity on which element was selected.
//In my code I'm throwing on more than 1 element found

async dragAndDrop(page, originSelector, destinationSelector) {
  await page.waitForSelector(originSelector)
  await page.waitForSelector(destinationSelector)
  const origin = await page.$(originSelector)
  const destination = await page.$(destinationSelector)
  const ob = await origin.boundingBox()
  const db = await destination.boundingBox()
    
  console.info(`Dragging from ${ob.x + ob.width / 2}, ${ob.y + ob.height / 2}`)
  await page.mouse.move(ob.x + ob.width / 2, ob.y + ob.height / 2)
  await page.mouse.down()
  console.info(`Dropping at   ${db.x + db.width / 2}, ${db.y + db.height / 2}`)
  await page.mouse.move(db.x + db.width / 2, db.y + db.height / 2)
  await page.mouse.up()
}

Обратите внимание, что поддержка перетаскивания в кукольнике по-прежнему реализована не полностью.

Ни одно из конкретных решений Puppeteer у меня не сработало, поэтому в итоге я написал собственный javascript в файл и импортировал его в Puppeteer (и в моем случае Jest).

drag-and-drop.js

async function dragAndDrop(source, target) {
  await page.evaluate((source, target) => {
    source = document.querySelector('#'+source);

    event = document.createEvent("CustomEvent");
    event.initCustomEvent("mousedown", true, true, null);
    event.clientX = source.getBoundingClientRect().top;
    event.clientY = source.getBoundingClientRect().left;
    source.dispatchEvent(event);

    event = document.createEvent("CustomEvent");
    event.initCustomEvent("dragstart", true, true, null);
    event.clientX = source.getBoundingClientRect().top;
    event.clientY = source.getBoundingClientRect().left;
    source.dispatchEvent(event);

    event = document.createEvent("CustomEvent");
    event.initCustomEvent("drag", true, true, null);
    event.clientX = source.getBoundingClientRect().top;
    event.clientY = source.getBoundingClientRect().left;
    source.dispatchEvent(event);


    target = document.querySelector('#'+target);

    event = document.createEvent("CustomEvent");
    event.initCustomEvent("dragover", true, true, null);
    event.clientX = target.getBoundingClientRect().top;
    event.clientY = target.getBoundingClientRect().left;
    target.dispatchEvent(event);

    event = document.createEvent("CustomEvent");
    event.initCustomEvent("drop", true, true, null);
    event.clientX = target.getBoundingClientRect().top;
    event.clientY = target.getBoundingClientRect().left;
    target.dispatchEvent(event);

    event = document.createEvent("CustomEvent");
    event.initCustomEvent("dragend", true, true, null);
    event.clientX = target.getBoundingClientRect().top;
    event.clientY = target.getBoundingClientRect().left;
    target.dispatchEvent(event);
  }, source, target);
}

test.js

const dragAndDrop = require('./drag-and-drop')

describe('when dragging and dropping todo', () => {

  it('should change order on DOM', async () => {
    const firstTodo = await page.evaluate(() => document.querySelectorAll('.input-container .input')[0].id);
    const secondTodo = await page.evaluate(() => document.querySelectorAll('.input-container .input')[1].id);

    dragAndDrop(firstTodo, secondTodo);

    const newFirstTodo = await page.evaluate(() => document.querySelectorAll('.input-container .input')[0].id);
    const newSecondTodo = await page.evaluate(() => document.querySelectorAll('.input-container .input')[1].id);

    expect(newFirstTodo).toEqual(secondTodo)
    expect(newSecondTodo).toEqual(firstTodo)
  });
});

Немного больше работы, чем встроенные функции Puppeteer, но, надеюсь, это достаточно простое решение для копирования и вставки для всех, кому нужен больший контроль над перетаскиванием.

clientX и clientY меняются местами по отношению к getBoundingClientRect (). top и left, но как только я это исправил, это сработало для меня, спасибо !!

Rego Sen 13.05.2020 00:33

Другие вопросы по теме