Home > Software design >  How to test mouse clientY in React testing (JEST)
How to test mouse clientY in React testing (JEST)

Time:12-02

useEffect(() => {
    const maybeHandler = (event: MouseEvent) => {
      menuData.forEach((el) => {
        if (el.hasActiveDropdown && event.clientY > 50) {
          handleCloseDropDown();
          // handleDropDown('0');
        }
      });
    };
    document.addEventListener('mousedown', maybeHandler);
    return () => document.removeEventListener('mousedown', maybeHandler);
  }, [handleCloseDropDown, menuData]);

I am used this useEffect to handle mulltip dropdowns in navbar component, navbar has fix height 50px so my logic is whenver use click outside the navbar the drop downs all are close.

I am unadble to test in JEST this clientY propery

CodePudding user response:

If you want to test the useEffect hook with the clientY property in Jest, you could consider using Jest's spyOn and mock functions to mock the addEventListener and removeEventListener methods on the document object, and then specify the return value for the clientY property in the mocked MouseEvent object that is passed to the event handler.

Here is an example of how you could do this:

const maybeHandler = jest.fn();

const mockAddEventListener = jest.spyOn(document, 'addEventListener');
const mockRemoveEventListener = jest.spyOn(document, 'removeEventListener');

useEffect(() => {
  maybeHandler(new MouseEvent('mousedown', {
    clientY: 100, // specify the return value for the clientY property
  }));

  document.addEventListener('mousedown', maybeHandler);

  return () => {
    document.removeEventListener('mousedown', maybeHandler);
  };
}, []);

// assert that the event listener was added and removed
expect(mockAddEventListener).toHaveBeenCalledWith('mousedown', maybeHandler);
expect(mockRemoveEventListener).toHaveBeenCalledWith('mousedown', maybeHandler);

// assert that the event handler was called
expect(maybeHandler).toHaveBeenCalled();

// assert the value of the clientY property in the mocked MouseEvent object
expect(maybeHandler.mock.calls[0][0].clientY).toBe(100);

You can then use this mocked event handler in your test cases to test the logic of your component that uses the useEffect hook.

CodePudding user response:

For my project I basically had a function that detected when the scroll happens This Project Was In React TypeScript

window.addEventListener('wheel', onScroll);
window.addEventListener('touchstart', handleTouchStart);        
window.addEventListener('touchmove', handleTouchMove);

and it calls back to onScroll

    function onScroll(e:any)   {
        if(Math.abs(e.deltaY) <= 35 || Scrolled) return;
        Scrolled = true;
        //console.log(e.deltaY);
        let direction = e.deltaY;
        //console.log(page);

        if(direction > 0) page  ;
        if(direction < 0) page--;

        //console.log(page);

        if(page <= 0) page = (0);
        if(page >= (pagesRef.current.length-1)) page = (pagesRef.current.length-1);

        pagesRef.current[page].scrollIntoView({behavior: "smooth"});
        setTimeout(()=>{Scrolled=false},800);
    }

and for touch / mobile devices

    function handleTouchStart(evt:any) {
        const firstTouch = getTouches(evt)[0];                                      
        xDown = firstTouch.clientX;                                      
        yDown = firstTouch.clientY;                                      
    };                                                
                                                                             
    function handleTouchMove(evt:any) {
        if ( ! xDown || ! yDown ) {
            return;
        }
    
        var xUp = evt.touches[0].clientX;                                    
        var yUp = evt.touches[0].clientY;
    
        var xDiff = xDown - xUp;
        var yDiff = yDown - yUp;
                                                                             
        if ( Math.abs( xDiff ) > Math.abs( yDiff ) ) {/*most significant*/
            if ( xDiff > 0 ) {
                /* right swipe */ 
            } else {
                /* left swipe */
            }                       
        } else {
            if ( yDiff > 0 ) {
                page  ;
            } else { 
                page--;
            }                                                                 
        }

        if(page <= 0) page = (0);
        if(page >= (pagesRef.current.length-1)) page = (pagesRef.current.length-1);

        pagesRef.current[page].scrollIntoView({behavior: "smooth"});

        /* reset values */
        xDown = null;
        yDown = null;                                             
    };

Hope this can help

  • Related