Clariity / react-chessboard

The React Chessboard Library used at ChessOpenings.co.uk. Inspired and adapted from the unmaintained Chessboard.jsx.
https://react-chessboard.vercel.app
MIT License
339 stars 101 forks source link

Automated testing with Jest #44

Open efilion opened 2 years ago

efilion commented 2 years ago

Had a hell of a time trying to figure this one out. Thought I would share the solution I found here to help anyone else trying to set up automated Jest tests with ReactChessboard.

Solution for writing automated tests with Jest

  1. npx create-react-app react-chessboard-jest-testing, cd react-chessboard-jest-testing
  2. npm i react-chessboard
  3. npm i --save-dev react-dnd-test-utils react-dnd-test-backend

    Getting Jest to play nicely with ESM modules

    package.json

    {
    ...
    "jest": {
    "transformIgnorePatterns": [
    "/node_modules/(?!(@?react-dnd[^/]*|dnd-core)/)"
    ]
    }
    }

    Writing the test

    src/App.test.js

    
    import React from 'react';
    import { act } from 'react-dom/test-utils';
    import { cleanup, render } from '@testing-library/react';
    import { fireDragDrop, tick } from 'react-dnd-test-utils';
    import { Chessboard as ReactChessboard } from 'react-chessboard';

/* act and await tick to ensure setup animation completes

afterEach(() => { cleanup() })

test('e2 to e4', async () => { let e2pawn = document.querySelector('[data-square=e2] [draggable]'); let e4square = document.querySelector('[data-square=e4]')

expect(e2pawn).toBeInTheDocument(); expect(e4square.querySelector('[draggable]')).not.toBeInTheDocument(); await fireDragDrop(e2pawn, e4square); expect(e2pawn).not.toBeInTheDocument(); expect(e4square.querySelector('[draggable]')).toBeInTheDocument(); })

---
Tested on:
- create-react-app v5.0.1
- node v16.14.0
- Ubuntu 20.04.4 LTS Focal x86_64
- `npm list`:
├── @testing-library/jest-dom@5.16.4
├── @testing-library/react@13.3.0
├── @testing-library/user-event@13.5.0
├── react-chessboard@1.3.0
├── react-dnd-test-backend@16.0.1
├── react-dnd-test-utils@16.0.1
├── react-dom@18.2.0
├── react-scripts@5.0.1
├── react@18.2.0
└── web-vitals@2.1.4

## Brainstorming possible improvements
Using querySelector is not necessarily a best practice. By adding aria roles and labels, those calls could be replaced with the more standard testing-library queries.

test('can find white pawn', () => { render( <>

</>

)

let e2pawn = screen.getByRole('widget', { name: /white e2 pawn/i }); expect(e2pawn).toBeInTheDocument(); })


I'm by no means an expert on accessibility. I went to both chess.com and lichess.org to see how they approach this, and it seems that they don't yet have any support for screen readers. Would be nice to get input from someone more knowledgeable about accessibility before making these changes and to think more broadly about the experience for visually impaired players.
Clariity commented 2 years ago

This is incredible, I've only had a brief read through as I'm very busy lately but when I get time I will try to turn this into some documentation that everyone can reference if they need to test, and I'll try to have a think about how testing could be improved/made easier as you suggested

Thank you so much for documenting this