Search code examples
reactjstestingmaterial-uitextareareact-testing-library

How to resize textarea by dragging in React Testing Library?


I need to test if Material UI's TextareaAutosize remains smooth while resizing. Since it uses an HTML textarea, I want to simulate resizing it with the mouse, using the grabber on the bottom-right corner.

I'm attempting to test the resizing behavior of TextareaAutosize component in the following way:

it('should not glitch when resizing textarea', function test() {
  if (/jsdom/.test(window.navigator.userAgent)) {
    this.skip();
  }

  const { container } = render(<TextareaAutosize />);
  const textarea = container.querySelector<HTMLTextAreaElement>('textarea')!;

  console.log('before textarea.style.height: ', textarea.style.height);

  // Get the element's dimensions
  const { top, left, width, height } = textarea.getBoundingClientRect();

  // Calculate coordinates of bottom-right corner
  const bottomRightX = left + width;
  const bottomRightY = top + height;

  fireEvent.mouseDown(textarea, { clientX: bottomRightX, clientY: bottomRightY });
  fireEvent.mouseMove(textarea, { clientX: bottomRightX + 50, clientY: bottomRightY + 50 });
  fireEvent.mouseUp(textarea);

  console.log('after textarea.style.height: ', textarea.style.height);
});

I've set it up to run the test in the browser, not on JSDOM, with this check:

  if (/jsdom/.test(window.navigator.userAgent)) {
    this.skip();
  }

However, I'm encountering an issue where the value of textarea.style.height remains the same before and after the mouse event, even though I expect it to change.

Chrome Headless 123.0.6312.4 (Windows 10) LOG: 'before textarea.style.height: ', '15px'
Chrome Headless 123.0.6312.4 (Windows 10) LOG: 'after textarea.style.height: ', '15px'

The height of the textarea should increase after the mouse interaction, but it seems like it's not actually resizing. I'm unsure if the dragging action is being properly simulated.


Solution

  • I resolved it using E2E testing with Playwright, instead of using React testing libraries. Below is the test implementation:

    First, the component rendered for testing:

    import * as React from 'react';
    import { TextareaAutosize } from '@mui/base/TextareaAutosize';
    
    function BasicTextareaAutosize() {
      return <TextareaAutosize data-testid="textarea" />;
    }
    
    export default BasicTextareaAutosize;
    

    Here's the e2e test:

    it('should not glitch when resizing', async () => {
      await renderFixture('TextareaAutosize/BasicTextareaAutosize');
    
      const textarea = await screen.getByTestId('textarea')!;
    
      // Get the element's dimensions
      const { x, y, width, height } = (await textarea.boundingBox())!;
    
      // Calculate coordinates of bottom-right corner
      const bottomRightX = x + width;
      const bottomRightY = y + height;
    
      // Get the initial height of textarea as a number
      const initialHeight = await textarea.evaluate((event) => parseFloat(event.style.height));
    
      // Move the mouse to the bottom-right corner, adjusting slightly to grab the resize handle
      await page.mouse.move(bottomRightX - 5, bottomRightY - 5);
    
      // Simulate a double click without releasing the mouse button (mouseup) to grab the resize handle
      await page.mouse.down();
      await page.mouse.up();
      await page.mouse.down();
    
      // Move the mouse to resize the textarea
      await page.mouse.move(bottomRightX + 50, bottomRightY + 50);
    
      // Assert that the textarea height has increased after resizing
      expect(await textarea.evaluate((event) => parseFloat(event.style.height))).to.be.greaterThan(
        initialHeight,
      );
    });