@@ -95,24 +95,35 @@ export function triggerActionForFileId(fileid: number, actionId: string) {
9595 . scrollIntoView ( )
9696 getActionButtonForFileId ( fileid )
9797 . click ( { force : true } ) // force to avoid issues with overlaying file list header
98- // Look up the action's clickable button. NcActions in
99- // apps/files/src/components/FileEntry/FileEntryActions.vue renders the first
100- // N children as standalone buttons inline in the row (the action carries
101- // `data-cy-files-list-row-action` directly on the <button>), and the rest
102- // inside the teleported menu popup (the action wraps a <button>). Use the
103- // menu id from aria-controls so we look in the right popup, and union with
104- // the inline-button location to cover both cases atomically.
10598 const escaped = CSS . escape ( actionId )
10699 getActionButtonForFileId ( fileid )
107100 . should ( 'have.attr' , 'aria-controls' )
108- . then ( ( menuId ) => cy . get ( [
109- `[data-cy-files-list-row-fileid="${ fileid } "] [data-cy-files-list-row-actions] button[data-cy-files-list-row-action="${ escaped } "]` ,
110- `#${ menuId } [data-cy-files-list-row-action="${ escaped } "] button` ,
111- `#${ menuId } button[data-cy-files-list-row-action="${ escaped } "]` ,
112- ] . join ( ', ' ) )
113- . first ( )
114- . should ( 'be.visible' )
115- . click ( ) )
101+ . then ( ( menuId ) => {
102+ // Wait for actions to be hydrated on this row. Until Vue finishes resolving
103+ // the row's `node` prop, `enabledRenderActions` is empty and the row's
104+ // inline area + opened popup contain no `[data-cy-files-list-row-action]`
105+ // element. That race is independent of app boot and is the residual flake
106+ // once OCP/OCA are ready. Wait up to 10 s for at least one action to mount.
107+ cy . get ( [
108+ `[data-cy-files-list-row-fileid="${ fileid } "] [data-cy-files-list-row-actions] [data-cy-files-list-row-action]` ,
109+ `#${ menuId } [data-cy-files-list-row-action]` ,
110+ ] . join ( ', ' ) , { timeout : 10000 } ) . should ( 'exist' )
111+ // Look up the action's clickable button. NcActions in
112+ // apps/files/src/components/FileEntry/FileEntryActions.vue renders the first
113+ // N children as standalone buttons inline in the row (the action carries
114+ // `data-cy-files-list-row-action` directly on the <button>), and the rest
115+ // inside the teleported menu popup (the action wraps a <button>). Use the
116+ // menu id from aria-controls so we look in the right popup, and union with
117+ // the inline-button location to cover both cases atomically.
118+ cy . get ( [
119+ `[data-cy-files-list-row-fileid="${ fileid } "] [data-cy-files-list-row-actions] button[data-cy-files-list-row-action="${ escaped } "]` ,
120+ `#${ menuId } [data-cy-files-list-row-action="${ escaped } "] button` ,
121+ `#${ menuId } button[data-cy-files-list-row-action="${ escaped } "]` ,
122+ ] . join ( ', ' ) )
123+ . first ( )
124+ . should ( 'be.visible' )
125+ . click ( )
126+ } )
116127}
117128
118129/**
@@ -134,25 +145,36 @@ export function triggerActionForFile(filename: string, actionId: string) {
134145 . scrollIntoView ( )
135146 getActionButtonForFile ( filename )
136147 . click ( { force : true } ) // force to avoid issues with overlaying file list header
137- // Look up the action's clickable button. NcActions in
138- // apps/files/src/components/FileEntry/FileEntryActions.vue renders the first
139- // N children as standalone buttons inline in the row (the action carries
140- // `data-cy-files-list-row-action` directly on the <button>), and the rest
141- // inside the teleported menu popup (the action wraps a <button>). Use the
142- // menu id from aria-controls so we look in the right popup, and union with
143- // the inline-button location to cover both cases atomically.
144148 const escapedAction = CSS . escape ( actionId )
145149 const escapedName = CSS . escape ( filename )
146150 getActionButtonForFile ( filename )
147151 . should ( 'have.attr' , 'aria-controls' )
148- . then ( ( menuId ) => cy . get ( [
149- `[data-cy-files-list-row-name="${ escapedName } "] [data-cy-files-list-row-actions] button[data-cy-files-list-row-action="${ escapedAction } "]` ,
150- `#${ menuId } [data-cy-files-list-row-action="${ escapedAction } "] button` ,
151- `#${ menuId } button[data-cy-files-list-row-action="${ escapedAction } "]` ,
152- ] . join ( ', ' ) )
153- . first ( )
154- . should ( 'be.visible' )
155- . click ( ) )
152+ . then ( ( menuId ) => {
153+ // Wait for actions to be hydrated on this row. Until Vue finishes resolving
154+ // the row's `node` prop, `enabledRenderActions` is empty and the row's
155+ // inline area + opened popup contain no `[data-cy-files-list-row-action]`
156+ // element. That race is independent of app boot and is the residual flake
157+ // once OCP/OCA are ready. Wait up to 10 s for at least one action to mount.
158+ cy . get ( [
159+ `[data-cy-files-list-row-name="${ escapedName } "] [data-cy-files-list-row-actions] [data-cy-files-list-row-action]` ,
160+ `#${ menuId } [data-cy-files-list-row-action]` ,
161+ ] . join ( ', ' ) , { timeout : 10000 } ) . should ( 'exist' )
162+ // Look up the action's clickable button. NcActions in
163+ // apps/files/src/components/FileEntry/FileEntryActions.vue renders the first
164+ // N children as standalone buttons inline in the row (the action carries
165+ // `data-cy-files-list-row-action` directly on the <button>), and the rest
166+ // inside the teleported menu popup (the action wraps a <button>). Use the
167+ // menu id from aria-controls so we look in the right popup, and union with
168+ // the inline-button location to cover both cases atomically.
169+ cy . get ( [
170+ `[data-cy-files-list-row-name="${ escapedName } "] [data-cy-files-list-row-actions] button[data-cy-files-list-row-action="${ escapedAction } "]` ,
171+ `#${ menuId } [data-cy-files-list-row-action="${ escapedAction } "] button` ,
172+ `#${ menuId } button[data-cy-files-list-row-action="${ escapedAction } "]` ,
173+ ] . join ( ', ' ) )
174+ . first ( )
175+ . should ( 'be.visible' )
176+ . click ( )
177+ } )
156178}
157179
158180/**
0 commit comments