react-beautiful-dnd-test-utils icon indicating copy to clipboard operation
react-beautiful-dnd-test-utils copied to clipboard

Focus assertion in `makeDnd` fails

Open shamsch opened this issue 1 year ago • 0 comments

Here is the test:

import React, {ReactNode} from "react";
import {render, screen, within} from "@testing-library/react";
import {
    mockGetComputedStyle,
    mockDndSpacing,
    makeDnd,
    DND_DIRECTION_UP,
    DND_DIRECTION_DOWN,
    DND_DRAGGABLE_DATA_ATTR,
} from "react-beautiful-dnd-test-utils";
import {DraggableProvided, DragDropContext, Droppable} from "react-beautiful-dnd";
import { TestDnd } from "../components/TestDnD";

jest.mock("react-beautiful-dnd", () => ({
    Droppable: ({children}) =>
        children(
            {
                draggableProps: {
                    style: {},
                },
                innerRef: jest.fn(),
            },
            {},
        ),
    Draggable: ({children}) =>
        children(
            {
                dragHandleProps: {
                    "aria-describedby": "",
                },
                draggableProps: {
                    style: {},
                },
                innerRef: jest.fn(),
            },
            {},
        ),
    DragDropContext: ({children}) => children,
})); //without this I get "TypeError: Cannot read properties of undefined (reading 'droppable')"

interface Item {
  id: string;
  content: string;
}

const initialItems: Item[] = [
  { id: '1', content: 'Item 1' },
  { id: '2', content: 'Item 2' },
  { id: '3', content: 'Item 3' },
];

const renderDnD = (): void => {
    const {container, debug} = render(
        <TestDnd initialItem={initialItems} />,
    );
    mockDndSpacing(container);
    debug();
}

const verifyOrder = (id: string, expectedOrder: string[]): void => {
    const items = within(screen.getByTestId(id))
        .map(item => item.textContent);
    expect(items.length).toBe(expectedOrder.length);
    expectedOrder.forEach((item, index) => {
        expect(items[index]).toBe(item);
    });
};

describe("DnD tests", () => {
    const mockUseContext: jest.SpyInstance = jest.spyOn(React, "useContext");

    beforeEach(() => {
        mockGetComputedStyle();
        mockUseContext.mockReturnValue({
            cvJson: {},
            uiJson: {},
        });
    });

    const makeGetDragElement = (id: string) => (): HTMLElement => {
        return screen.getByTestId(id);
    };

    describe("Moving single items", () => {
        test("Move a item up", async () => {
            await renderDnD();

            await makeDnd({
                getDragElement: makeGetDragElement("item-2"),
                direction: DND_DIRECTION_UP,
                positions: 1,
            });

            verifyOrder("dnd-test", ["item 2", "item 1", "item 3"]);
        });
    });
});

Here's the component:

import React, { useState } from 'react';
import { DragDropContext, Droppable, Draggable, DropResult } from 'react-beautiful-dnd';

interface Item {
  id: string;
  content: string;
}

interface TestDndProps {
  initialItem: Item[];
}

export const TestDnd: React.FC<TestDndProps> = ({initialItem}) => {
  const [items, setItems] = useState(initialItem);

  const handleOnDragEnd = (result: DropResult) => {
    if (!result.destination) return;
    const itemsArray: Item[] = Array.from(items);
    const [reorderedItem] = itemsArray.splice(result.source.index, 1);
    itemsArray.splice(result.destination.index, 0, reorderedItem);

    setItems(itemsArray);
  }

  return (
    <DragDropContext onDragEnd={handleOnDragEnd}>
      <Droppable droppableId="items">
        {provided => (
          <ul {...provided.droppableProps} ref={provided.innerRef} data-testid="dnd-test">
            {items.map(({id, content}, index) => (
              <Draggable key={id} draggableId={id} index={index}>
                {provided => (
                  <li ref={provided.innerRef} {...provided.draggableProps} {...provided.dragHandleProps} data-testid={`item-${id}`}>
                    {content}
                  </li>
                )}
              </Draggable>
            ))}
            {provided.placeholder}
          </ul>
        )}
      </Droppable>
    </DragDropContext>
  );
}

Error I'm getting: image

shamsch avatar Jun 26 '23 10:06 shamsch