Skip to content

Commit d01069b

Browse files
committed
fix(UploadPicker): Add accessible information for uploader button
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
1 parent f52466a commit d01069b

File tree

2 files changed

+38
-36
lines changed

2 files changed

+38
-36
lines changed

cypress/components/UploadPicker/UploadPicker.cy.ts

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@
33
* SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
44
* SPDX-License-Identifier: AGPL-3.0-or-later
55
*/
6-
// dist file might not be built when running eslint only
7-
// eslint-disable-next-line import/no-unresolved,n/no-missing-import
8-
import { Folder, Permission, addNewFileMenuEntry, type Entry } from '@nextcloud/files'
6+
import { Folder, Permission } from '@nextcloud/files'
97
import { generateRemoteUrl } from '@nextcloud/router'
108
import { UploadPicker, UploadStatus, getUploader } from '../../../lib/index.ts'
119

@@ -39,8 +37,9 @@ describe('UploadPicker rendering', () => {
3937
}
4038
cy.mount(UploadPicker, { propsData })
4139
cy.get('[data-cy-upload-picker]').should('be.visible')
42-
cy.get('[data-cy-upload-picker]').shouldHaveTrimmedText('New')
40+
cy.get('[data-cy-upload-picker]').should('contain.text', 'New')
4341
cy.get('[data-cy-upload-picker] [data-cy-upload-picker-input]').should('exist')
42+
cy.get('[data-cy-upload-picker] [data-cy-upload-picker-progress]').should('not.be.visible')
4443
})
4544

4645
it('Does NOT render without a destination', () => {
@@ -68,22 +67,22 @@ describe('UploadPicker valid uploads', () => {
6867
cy.mount(UploadPicker, { propsData }).as('uploadPicker')
6968

7069
// Label is displayed before upload
71-
cy.get('[data-cy-upload-picker]').shouldHaveTrimmedText('New')
70+
cy.get('[data-cy-upload-picker]')
71+
.contains('button', 'New')
72+
.should('be.visible')
7273

7374
// Check and init aliases
7475
cy.get('[data-cy-upload-picker] [data-cy-upload-picker-input]').as('input').should('exist')
75-
cy.get('[data-cy-upload-picker] .upload-picker__progress').as('progress').should('exist')
76+
cy.get('[data-cy-upload-picker] [data-cy-upload-picker-progress]').as('progress').should('exist')
7677
})
7778

7879
afterEach(() => resetDocument())
7980

8081
it('Uploads a file', () => {
81-
// Intercept single upload
82+
const { promise, resolve } = Promise.withResolvers<void>()
8283
cy.intercept('PUT', '/remote.php/dav/files/*/*', (req) => {
83-
req.reply({
84-
statusCode: 201,
85-
delay: 2000,
86-
})
84+
req.reply({ statusCode: 201 })
85+
req.on('response', async () => await promise)
8786
}).as('upload')
8887

8988
cy.get('@input').attachFile({
@@ -95,16 +94,20 @@ describe('UploadPicker valid uploads', () => {
9594
lastModified: new Date().getTime(),
9695
})
9796

98-
cy.get('[data-cy-upload-picker] .upload-picker__progress')
99-
.as('progress')
100-
.should('be.visible')
101-
102-
// Label gets hidden during upload
103-
cy.get('[data-cy-upload-picker]').should('not.have.text', 'New')
97+
cy.get('@progress').should('be.visible')
98+
cy.get('[data-cy-upload-picker]')
99+
.within(() => {
100+
// Label gets hidden during upload
101+
cy.contains('button', 'New').should('not.exist')
102+
// but the button exists
103+
cy.get('button[data-cy-upload-picker-add]')
104+
.should('be.visible')
105+
.and('have.attr', 'aria-label', 'New')
106+
})
107+
.then(() => resolve())
104108

105109
cy.wait('@upload').then(() => {
106-
cy.get('[data-cy-upload-picker] .upload-picker__progress')
107-
.as('progress')
110+
cy.get('@progress')
108111
.should('not.be.visible')
109112

110113
// Label is displayed again after upload

lib/components/UploadPicker.vue

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
data-cy-upload-picker>
1111
<!-- New button -->
1212
<NcButton v-if="!haveMenu"
13+
:aria-label="buttonLabel"
1314
:disabled="disabled"
1415
data-cy-upload-picker-add
1516
data-cy-upload-picker-menu-entry="upload-file"
@@ -18,12 +19,14 @@
1819
<template #icon>
1920
<IconPlus :size="20" />
2021
</template>
21-
{{ buttonName }}
22+
<template v-if="!isUploading" #default>
23+
{{ buttonLabel }}
24+
</template>
2225
</NcButton>
2326

2427
<NcActions v-else
2528
:aria-label="buttonLabel"
26-
:menu-name="buttonName"
29+
:menu-name="buttonLabel"
2730
:open.sync="openedMenu"
2831
:type="primary ? 'primary' : 'secondary'">
2932
<template #icon>
@@ -301,17 +304,21 @@ export default defineComponent({
301304
hasFailure(): boolean {
302305
return this.queue.some((upload: Upload) => upload.status === UploadStatus.FAILED)
303306
},
307+
isAssembling(): boolean {
308+
return this.queue.some((upload: Upload) => upload.status === UploadStatus.ASSEMBLING)
309+
},
304310
isUploading(): boolean {
305311
return this.queue.some((upload: Upload) => upload.status !== UploadStatus.CANCELLED)
306312
},
307313
isOnlyAssembling(): boolean {
308-
return this.queue.every((upload: Upload) => (
309-
// ignore empty uploads or meta uploads
310-
upload.size === 0
311-
// all the uploads are assembling or finished
312-
|| upload.status === UploadStatus.ASSEMBLING
313-
|| upload.status === UploadStatus.FINISHED
314-
))
314+
return this.isAssembling
315+
&& this.queue.every((upload: Upload) => (
316+
// ignore empty uploads or meta uploads
317+
upload.size === 0
318+
// all the uploads are assembling or finished
319+
|| upload.status === UploadStatus.ASSEMBLING
320+
|| upload.status === UploadStatus.FINISHED
321+
))
315322
},
316323
isPaused(): boolean {
317324
return this.uploadManager.info?.status === UploaderStatus.PAUSED
@@ -321,14 +328,6 @@ export default defineComponent({
321328
return this.noMenu ? t('Upload') : t('New')
322329
},
323330
324-
// Hide the button text if we're uploading
325-
buttonName(): string|undefined {
326-
if (this.isUploading) {
327-
return undefined
328-
}
329-
return this.buttonLabel
330-
},
331-
332331
haveMenu(): boolean {
333332
return !((this.noMenu || this.newFileMenuEntries.length === 0) && !this.canUploadFolders)
334333
},

0 commit comments

Comments
 (0)