describe ( 'ContextMenu' , ( ) => { describe ( 'given submenu user' , ( ) => { beforeEach ( ( ) => { cy . visitStory ( 'contextmenu--submenus' ) ; cy . findByText ( 'Right Click Here' ) . rightclick ( ) ; } ) ; describe ( 'when using pointer' , ( ) => { it ( 'should close open submenus and reopen the root menu when right clicking trigger' , ( ) => { pointerOver ( 'Bookmarks →' ) ; cy . findByText ( 'Inbox' ) . should ( 'be.visible' ) ; cy . findByText ( 'Right Click Here' ) . rightclick ( { force : true } ) ; cy . findByText ( 'New Tab' ) . should ( 'be.visible' ) ; cy . findByText ( 'Inbox' ) . should ( 'not.exist' ) ; } ) ; it ( 'should open submenu and not focus first item when moving pointer over trigger' , ( ) => { pointerOver ( 'Bookmarks →' ) ; cy . findByText ( 'Inbox' ) . should ( 'not.be.focused' ) ; } ) ; it ( 'should not close when moving pointer to submenu and back to parent trigger' , ( ) => { pointerOver ( 'Bookmarks →' ) ; pointerOver ( 'Inbox' ) ; pointerOver ( 'Bookmarks →' ) ; cy . findByText ( 'Inbox' ) . should ( 'be.visible' ) ; } ) ; it ( 'should close submenu when moving pointer away but remain open when moving towards' , { viewportWidth : 550 , } , ( ) => { pointerOver ( 'Bookmarks →' ) ; cy . findByText ( 'Inbox' ) . should ( 'be.visible' ) ; pointerExitRightToLeft ( 'Bookmarks →' ) ; cy . findByText ( 'Inbox' ) . should ( 'not.exist' ) ; pointerOver ( 'Bookmarks →' ) ; cy . findByText ( 'Inbox' ) . should ( 'be.visible' ) ; pointerExitLeftToRight ( 'Bookmarks →' ) ; cy . findByText ( 'Inbox' ) . should ( 'be.visible' ) ; pointerOver ( 'Modulz →' ) ; cy . findByText ( 'Radix' ) . should ( 'be.visible' ) ; pointerExitLeftToRight ( 'Modulz →' ) ; cy . findByText ( 'Radix' ) . should ( 'not.exist' ) ; pointerOver ( 'Modulz →' ) ; cy . findByText ( 'Radix' ) . should ( 'be.visible' ) ; pointerExitRightToLeft ( 'Modulz →' ) ; cy . findByText ( 'Radix' ) . should ( 'be.visible' ) ; } ) ; it ( 'should close open submenu when moving pointer to any item in parent menu' , ( ) => { pointerOver ( 'Bookmarks →' ) ; pointerOver ( 'Inbox' ) ; pointerOver ( 'New Tab' ) ; cy . findByText ( 'Inbox' ) . should ( 'not.exist' ) ; pointerOver ( 'Bookmarks →' ) ; pointerOver ( 'Inbox' ) ; pointerOver ( 'Print…' ) ; cy . findByText ( 'Inbox' ) . should ( 'not.exist' ) ; pointerOver ( 'Bookmarks →' ) ; pointerOver ( 'Inbox' ) ; pointerOver ( 'Tools →' ) ; cy . findByText ( 'Inbox' ) . should ( 'not.exist' ) ; pointerOver ( 'Bookmarks →' ) ; pointerOver ( 'Inbox' ) ; pointerOver ( 'History →' ) ; cy . findByText ( 'Inbox' ) . should ( 'not.exist' ) ; } ) ; it ( 'should close unassociated submenus when moving pointer back to the root trigger' , ( ) => { pointerOver ( 'Bookmarks →' ) ; pointerOver ( 'Modulz →' ) ; pointerOver ( 'Radix' ) ; pointerOver ( 'Bookmarks →' ) ; cy . findByText ( 'Inbox' ) . should ( 'be.visible' ) ; cy . findByText ( 'Radix' ) . should ( 'not.exist' ) ; } ) ; it ( 'should close all menus when clicking item in any menu, or clicking outside' , ( ) => { cy . findByText ( 'New Tab' ) . click ( ) ; cy . findByText ( 'New Tab' ) . should ( 'not.exist' ) ; cy . findByText ( 'Right Click Here' ) . rightclick ( ) ; pointerOver ( 'Bookmarks →' ) ; cy . findByText ( 'Inbox' ) . click ( ) ; cy . findByText ( 'New Tab' ) . should ( 'not.exist' ) ; cy . findByText ( 'Inbox' ) . should ( 'not.exist' ) ; cy . findByText ( 'Right Click Here' ) . rightclick ( ) ; cy . get ( 'body' ) . click ( { force : true } ) ; cy . findByText ( 'New Tab' ) . should ( 'not.exist' ) ; } ) ; } ) ; describe ( 'When using keyboard' , ( ) => { it ( 'should not open submenu when moving focus to trigger' , ( ) => { cy . findByText ( 'Bookmarks →' ) . focus ( ) ; cy . findByText ( 'Inbox' ) . should ( 'not.exist' ) ; } ) ; it ( 'should open submenu and focus first item when pressing right arrow, enter or space key' , ( ) => { function shouldOpenOnKeydown ( key ) { cy . findByText ( 'Bookmarks →' ) . trigger ( 'keydown' , { key } ) ; cy . findByText ( 'Inbox' ) . should ( 'be.focused' ) . trigger ( 'keydown' , { key : 'ArrowLeft' } ) ; } shouldOpenOnKeydown ( ' ' ) ; shouldOpenOnKeydown ( 'Enter' ) ; shouldOpenOnKeydown ( 'ArrowRight' ) ; } ) ; it ( 'should close only the focused submenu when pressing left arrow key' , ( ) => { cy . findByText ( 'Bookmarks →' ) . type ( '{enter}' ) ; cy . findByText ( 'Modulz →' ) . type ( '{enter}' ) ; cy . findByText ( 'Stitches' ) . type ( '{leftarrow}' ) . should ( 'not.exist' ) ; cy . findByText ( 'Modulz →' ) . should ( 'be.visible' ) ; cy . findByText ( 'New Window' ) . should ( 'be.visible' ) ; } ) ; it ( 'should close all menus when pressing escape, enter or space key on any item' , ( ) => { cy . findByText ( 'Bookmarks →' ) . type ( '{esc}' ) . should ( 'not.exist' ) ; cy . findByText ( 'Right Click Here' ) . rightclick ( ) ; cy . findByText ( 'Bookmarks →' ) . type ( '{enter}' ) ; cy . findByText ( 'Inbox' ) . type ( '{esc}' ) . should ( 'not.exist' ) ; cy . findByText ( 'New Window' ) . should ( 'not.exist' ) ; } ) ; it ( 'should scope typeahead behaviour to the active menu' , ( ) => { pointerOver ( 'Bookmarks →' ) ; pointerOver ( 'Modulz →' ) ; cy . findByText ( 'Stitches' ) . focus ( ) . type ( 'Inbox' ) ; cy . findByText ( 'Inbox' ) . should ( 'not.have.focus' ) ; pointerOver ( 'Notion' ) . focus ( ) . type ( 'Inbox' ) ; cy . findByText ( 'Inbox' ) . should ( 'have.focus' ) ; } ) ; } ) ; describe ( 'When using pointer in RTL' , ( ) => { beforeEach ( ( ) => { cy . findByText ( 'Right-to-left' ) . click ( { force : true } ) ; cy . findByText ( 'Right Click Here' ) . rightclick ( ) ; } ) ; it ( 'should close submenu when pointer moves away but remain open when moving towards' , { viewportWidth : 550 , } , ( ) => { pointerOver ( 'Bookmarks →' ) ; cy . findByText ( 'Inbox' ) . should ( 'be.visible' ) ; pointerExitLeftToRight ( 'Bookmarks →' ) ; cy . findByText ( 'Inbox' ) . should ( 'not.exist' ) ; pointerOver ( 'Bookmarks →' ) ; cy . findByText ( 'Inbox' ) . should ( 'be.visible' ) ; pointerExitRightToLeft ( 'Bookmarks →' ) ; cy . findByText ( 'Inbox' ) . should ( 'be.visible' ) ; pointerOver ( 'Modulz →' ) ; cy . findByText ( 'Radix' ) . should ( 'be.visible' ) ; pointerExitRightToLeft ( 'Modulz →' ) ; cy . findByText ( 'Radix' ) . should ( 'not.exist' ) ; pointerOver ( 'Modulz →' ) ; cy . findByText ( 'Radix' ) . should ( 'be.visible' ) ; pointerExitLeftToRight ( 'Modulz →' ) ; cy . findByText ( 'Radix' ) . should ( 'be.visible' ) ; } ) ; } ) ; describe ( 'When using keyboard in RTL' , ( ) => { beforeEach ( ( ) => { cy . findByText ( 'Right-to-left' ) . click ( { force : true } ) ; cy . findByText ( 'Right Click Here' ) . rightclick ( ) ; } ) ; it ( 'should open submenu and focus first item when pressing left arrow key but close when pressing right arrow key' , ( ) => { cy . findByText ( 'Bookmarks →' ) . trigger ( 'keydown' , { key : 'ArrowLeft' } ) ; cy . findByText ( 'Inbox' ) . should ( 'be.focused' ) . trigger ( 'keydown' , { key : 'ArrowRight' } ) . and ( 'not.exist' ) ; cy . findByText ( 'New Tab' ) . should ( 'be.visible' ) ; } ) ; } ) ; } ) ; function pointerExitRightToLeft ( elementText ) { return cy . findByText ( elementText ) . should ( 'be.visible' ) . realHover ( { position : 'right' } ) . realHover ( { position : 'bottomLeft' } ) . trigger ( 'pointerout' , 'bottomLeft' , { pointerType : 'mouse' } ) ; } function pointerExitLeftToRight ( elementText ) { return cy . findByText ( elementText ) . should ( 'be.visible' ) . realHover ( { position : 'left' } ) . realHover ( { position : 'bottomRight' } ) . trigger ( 'pointerout' , 'bottomRight' , { pointerType : 'mouse' } ) ; } function pointerOver ( elementText ) { return cy . findByText ( elementText ) . should ( 'be.visible' ) . realHover ( ) ; } } ) ;