Drag and Drop with React. Writing E2E tests using Playwright

JavaScript React Testing

Web applications are becoming increasingly complex. While that’s the case, we must ensure the interface is intuitive and easy to use. By allowing our users to drag and drop elements across the screen, we can simplify many tasks, such as reordering lists or grouping items.

In this article, we learn how to implement the drag-and-drop functionality without third-party libraries by implementing a simple To-Do list. We also learn how to ensure it works as expected by writing End-to-End (E2E) tests with Playwright.

Check out this repository if you want to see the full code from this article.

Creating a To-Do List application

Let’s create a simple application that uses drag-and-drop to manage its state.

Managing a list of strings

To implement our To-Do list, we need to manage two lists of strings. One contains a list of tasks to do, and the other holds the completed tasks. We can simplify it by creating a generic custom hook.

useList.tsx

Above, we have two methods – one for adding items and one for removing them. We can use it twice to handle the state of two different lists.

Handling the input for creating new tasks

To be able to add elements to our lists, we have to create an input and let the users interact with it to put the name of the new task.

useNewItemInput.tsx

Dragging and dropping

To handle dragging and dropping, we can use a set of event handlers. First, let’s see them in action in a straightforward example.

draggable

By default, the attribute on each element is set to , which allows certain elements, such as images, to be dragged. We should set it to true to ensure that our element can be dragged properly.

onDragStart

The event occurs when the user starts to drag an element.

onDragOver

By default, browsers prevent items from being dropped on a particular element. To override that, we need to use the event, which is fired when an element is dragged over a drop target. Calling enables it to receive events.

onDrop

The event happens when the user drops the item on the target. This works if we use the event properly and call the function.

Implementing the drag-and-drop functionalities

Let’s create a custom hook to handle the drag-and-drop functionalities in our To-Do List application.

useDragAndDrop.tsx

Please notice that is a currying function that returns another function.

We will call the function when the user starts dragging a particular item on the list. What’s important is that we store which item was dragged. We will need to know it later.

Then, we have two separate functions that handle dropping the item:

  • that we will call when the user drops an item on the list of completed tasks
    • it adds the currently dragged item to the list of completed tasks and removes it from the to-do tasks
  • that we will need to call when the user drops an item on the list of to-do tasks
    • it removes the currently dragged item from the list of completed tasks and appends it to the to-do tasks

We also have the function, which we must use to handle the event.

Combining all of our custom hooks

We now have custom hooks for every aspect of our application:

  • that handles the state of the input used for creating new tasks
  • that manages the state of a particular list of tasks
  • which contains the logic of dragging and dropping tasks on different lists.

Let’s combine all of the above in a single React component.

ToDoList.tsx

In the component, we render all items from a particular list and attach event listeners related to dragging and dropping.

List.tsx

Thanks to all of the above, we now have a fully functional application that allows us to create tasks and move them between two lists by dragging and dropping.

Testing with Playwright

Let’s start by creating a straightforward test that adds the item and checks if it appears on the To-Do list.

ToDoList.test.ts

Above, we use to navigate to our website thanks to using the configuration property and environment variables. If you want to know more, check out JavaScript testing #17. Introduction to End-to-End testing with Playwright

Testing the dragging functionality

To simulate dragging and dropping with Playwright, we need to use the function.

ToDoList.test.ts

When calling the function, we provide the target – in this case, the list of completed tasks. All that’s left to do is to check if the task was moved from one list to another.

Summary

In this article, we’ve created a simple To-Do List application using React without relying on any third-party libraries. Thanks to that, we’ve better understood how native events work, allowing us to handle dragging and dropping. We also made sure to split the logic of our application into small and easy-to-understand custom React hooks.

In addition, we learned how to use Playwright to write End-to-End tests that simulate dragging and dropping in a browser and ensure our application is working as expected.

Subscribe
Notify of
guest
1 Comment
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Fedasa
Fedasa
9 days ago

I like your series, they are very nice contents