Mirror: React hooks for accessible, common web interactions. UI super powers without the UI.
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Add tests for makePriorityHook / usePriority

+137
+137
src/__tests__/usePriority.test.tsx
··· 1 + import React, { ReactNode, useState, useLayoutEffect, useRef } from 'react'; 2 + import { mount } from '@cypress/react'; 3 + 4 + import { makePriorityHook } from '../usePriority'; 5 + 6 + const usePriority = makePriorityHook(); 7 + 8 + const FocusOnPriority = ( 9 + { id, children = null }: 10 + { id: string, children?: ReactNode } 11 + ) => { 12 + const ref = useRef<HTMLDivElement>(null); 13 + const hasPriority = usePriority(ref); 14 + 15 + useLayoutEffect(() => { 16 + if (hasPriority && ref.current) { 17 + ref.current!.focus(); 18 + } 19 + }, [hasPriority, ref]); 20 + 21 + return ( 22 + <div tabIndex={-1} ref={ref} id={id}> 23 + {children} 24 + </div> 25 + ); 26 + }; 27 + 28 + it('allows sole element to take priority', () => { 29 + mount( 30 + <FocusOnPriority id="only" /> 31 + ); 32 + 33 + cy.focused().should('have.id', 'only'); 34 + }); 35 + 36 + it('tracks priority of sibling elements in order', () => { 37 + mount( 38 + <main> 39 + <FocusOnPriority id="first" /> 40 + <FocusOnPriority id="second" /> 41 + </main> 42 + ); 43 + 44 + cy.focused().should('have.id', 'second'); 45 + }); 46 + 47 + it('tracks priority of nested elements in order', () => { 48 + mount( 49 + <FocusOnPriority id="outer"> 50 + <FocusOnPriority id="inner" /> 51 + </FocusOnPriority> 52 + ); 53 + 54 + cy.focused().should('have.id', 'inner'); 55 + }); 56 + 57 + it('should switch priorities of sibling elements as needed', () => { 58 + const App = () => { 59 + const [visible, setVisible] = useState(true); 60 + 61 + return ( 62 + <main> 63 + <FocusOnPriority id="first" /> 64 + {visible && <FocusOnPriority id="second" />} 65 + <button onClick={() => setVisible(false)}>switch</button> 66 + </main> 67 + ); 68 + }; 69 + 70 + mount(<App />); 71 + 72 + cy.focused().should('have.id', 'second'); 73 + cy.get('button').first().click(); 74 + cy.focused().should('have.id', 'first'); 75 + }); 76 + 77 + it('should switch priorities of nested elements as needed', () => { 78 + const App = () => { 79 + const [visible, setVisible] = useState(true); 80 + 81 + return ( 82 + <main> 83 + <FocusOnPriority id="outer"> 84 + {visible && <FocusOnPriority id="inner" />} 85 + </FocusOnPriority> 86 + <button onClick={() => setVisible(false)}>switch</button> 87 + </main> 88 + ); 89 + }; 90 + 91 + mount(<App />); 92 + 93 + cy.focused().should('have.id', 'inner'); 94 + cy.get('button').first().click(); 95 + cy.focused().should('have.id', 'outer'); 96 + }); 97 + 98 + it('should preserve priorities when non-prioritised item is removed', () => { 99 + const App = () => { 100 + const [visible, setVisible] = useState(true); 101 + 102 + return ( 103 + <main> 104 + {visible && <FocusOnPriority id="first" />} 105 + <FocusOnPriority id="second" /> 106 + <button onClick={() => setVisible(false)}>switch</button> 107 + </main> 108 + ); 109 + }; 110 + 111 + mount(<App />); 112 + 113 + cy.focused().should('have.id', 'second'); 114 + cy.get('button').first().click(); 115 + cy.get('button').first().should('have.focus'); 116 + }); 117 + 118 + it('should update priorities when new prioritised item is added', () => { 119 + const App = () => { 120 + const [visible, setVisible] = useState(false); 121 + 122 + return ( 123 + <main> 124 + <FocusOnPriority id="first" /> 125 + <FocusOnPriority id="second" /> 126 + {visible && <FocusOnPriority id="third" />} 127 + <button onClick={() => setVisible(true)}>switch</button> 128 + </main> 129 + ); 130 + }; 131 + 132 + mount(<App />); 133 + 134 + cy.focused().should('have.id', 'second'); 135 + cy.get('button').first().click(); 136 + cy.focused().should('have.id', 'third'); 137 + });