Skip to content

Commit 6ef928b

Browse files
committed
test(cypress): wait for row actions to hydrate before clicking
Signed-off-by: Git'Fellow <12234510+solracsf@users.noreply.github.com>
1 parent f6584fa commit 6ef928b

1 file changed

Lines changed: 52 additions & 30 deletions

File tree

cypress/e2e/files/FilesUtils.ts

Lines changed: 52 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)