Search code examples
reactjstestingdrag-and-dropcypressreact-testing-library

How can I test a resizable circle SVG element?


Trying to figure out how to properly test a resizable <circle> svg element. I am new to React Testing Library, so I'm unsure if this is possible with RTL (with the Mocha test framework) or if I should use Cypress.

Let's say I have a circle element:

<circle data-testid='circle-element' cx="100" cy="100" r="50"/>

NOTE: 0,0 origin is at the top left.

The center of the circle is located at x=100, y=100 with a radius of 50.

enter image description here

Located on the edge of the circle at x=150, y=100 is a Draghandle where a user can click and drag to resize the circle.

<DragHandle
  data-testid='circle-draghandle'
  x={handleX}
  y={handleY}
  dragMove={onHandleDrag}
/>

If a user clicks on the Draghandle at its original location of x=150, y=100 and drags to x=200, y=100, we expect the circle radius to now be 100.

NOTE: the center of the circle is unchanged; still at x=100, y=100.

enter image description here

How can I test this?

I did figure out how to test if the circle rendered properly using React Testing Library with given coordinates and radius:

it('should render a Circle with the coordinates provided', function () {
    render(<Circle mark={{ cx: 100, cy: 100, r: 50}} />)

    expect(screen.getByTestId('circle-element'))
      .to.have.attr('r')
      .to.equal('50')
  })

NOTE: <Circle> is our component where the actual <circle> svg element lives.

Any help with testing the resizing part what be amazing!

Thank you.


Solution

  • OK - finally have a solution using React Testing Library and user-events@14!

    Hopefully this will help someone else.

    user-events must be 14.0 or higher.

    import userEvent in testing file:

    import userEvent from '@testing-library/user-event'
    

    The test:

    describe('Circle tool', function () {
      let mark
      beforeEach(function () {
        mark = CircleMark.create({
          id: 'circle1',
          toolType: 'circle',
          x_center: 200,
          y_center: 200,
          r: 50
        })
      })
    
      it('should change the radius when drag handle is moved', async () => {
        const user = userEvent.setup()
    
        render(<Circle mark={mark} />)
    
        expect(mark.x_center).to.equal(200)
        expect(mark.y_center).to.equal(200)
        expect(mark.r).to.equal(50)
    
        // click on dragHandle
        // move dragHandle
        // release mouse button
        const circleDragHandle = screen.getByTestId('draghandle')
        await user.pointer([
          { keys: '[MouseLeft>]', target: circleDragHandle },
          { coords: { x: 300, y: 200 } },
          { keys: '[/MouseLeft]' }
        ])
    
        expect(mark.x_center).to.equal(200)
        expect(mark.y_center).to.equal(200)
        expect(mark.r).to.equal(100)
      })
    })