@@ -62,6 +62,36 @@ export function getInlineActionEntryForFile(file: string, actionId: string) {
6262 return cy . get ( `[data-cy-files-list-row-name="${ CSS . escape ( file ) } "] [data-cy-files-list-row-action="${ CSS . escape ( actionId ) } "]` )
6363}
6464
65+ /**
66+ * Open the actions menu of a file row and wait until it is really open.
67+ *
68+ * Async row re-renders (preview and share-status loading) re-mount the
69+ * NcActions component, which silently closes a menu that was just opened.
70+ * So click only while the toggle reports "closed" and poll aria-expanded,
71+ * retrying until the open state sticks.
72+ *
73+ * @param getActionButton query for the actions menu toggle of the row
74+ * @param attempts remaining retries before giving up
75+ */
76+ function openActionsMenu ( getActionButton : ( ) => Cypress . Chainable < JQuery < HTMLElement > > , attempts = 5 ) {
77+ getActionButton ( ) . then ( ( $toggle ) => {
78+ if ( $toggle . attr ( 'aria-expanded' ) !== 'true' ) {
79+ cy . wrap ( $toggle ) . click ( { force : true } ) // force to avoid issues with overlaying file list header
80+ }
81+ } )
82+ getActionButton ( ) . then ( ( $toggle ) => {
83+ if ( $toggle . attr ( 'aria-expanded' ) === 'true' ) {
84+ return
85+ }
86+ if ( attempts <= 0 ) {
87+ throw new Error ( 'Actions menu did not open' )
88+ }
89+ // eslint-disable-next-line cypress/no-unnecessary-waiting -- give the popover time to render before retrying
90+ cy . wait ( 200 )
91+ openActionsMenu ( getActionButton , attempts - 1 )
92+ } )
93+ }
94+
6595/**
6696 *
6797 * @param fileid
@@ -70,8 +100,7 @@ export function getInlineActionEntryForFile(file: string, actionId: string) {
70100export function triggerActionForFileId ( fileid : number , actionId : string ) {
71101 getActionButtonForFileId ( fileid )
72102 . scrollIntoView ( )
73- getActionButtonForFileId ( fileid )
74- . click ( { force : true } ) // force to avoid issues with overlaying file list header
103+ openActionsMenu ( ( ) => getActionButtonForFileId ( fileid ) )
75104 getActionEntryForFileId ( fileid , actionId )
76105 . find ( 'button' )
77106 . should ( 'be.visible' )
@@ -86,8 +115,7 @@ export function triggerActionForFileId(fileid: number, actionId: string) {
86115export function triggerActionForFile ( filename : string , actionId : string ) {
87116 getActionButtonForFile ( filename )
88117 . scrollIntoView ( )
89- getActionButtonForFile ( filename )
90- . click ( { force : true } ) // force to avoid issues with overlaying file list header
118+ openActionsMenu ( ( ) => getActionButtonForFile ( filename ) )
91119 getActionEntryForFile ( filename , actionId )
92120 . find ( 'button' )
93121 . should ( 'be.visible' )
0 commit comments