Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 23 additions & 20 deletions cypress/components/UploadPicker/UploadPicker.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@
* SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
// dist file might not be built when running eslint only
// eslint-disable-next-line import/no-unresolved,n/no-missing-import
import { Folder, Permission, addNewFileMenuEntry, type Entry } from '@nextcloud/files'
import { Folder, Permission } from '@nextcloud/files'
import { generateRemoteUrl } from '@nextcloud/router'
import { UploadPicker, UploadStatus, getUploader } from '../../../lib/index.ts'

Expand Down Expand Up @@ -39,8 +37,9 @@ describe('UploadPicker rendering', () => {
}
cy.mount(UploadPicker, { propsData })
cy.get('[data-cy-upload-picker]').should('be.visible')
cy.get('[data-cy-upload-picker]').shouldHaveTrimmedText('New')
cy.get('[data-cy-upload-picker]').should('contain.text', 'New')
cy.get('[data-cy-upload-picker] [data-cy-upload-picker-input]').should('exist')
cy.get('[data-cy-upload-picker] [data-cy-upload-picker-progress]').should('not.be.visible')
})

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

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

// Check and init aliases
cy.get('[data-cy-upload-picker] [data-cy-upload-picker-input]').as('input').should('exist')
cy.get('[data-cy-upload-picker] .upload-picker__progress').as('progress').should('exist')
cy.get('[data-cy-upload-picker] [data-cy-upload-picker-progress]').as('progress').should('exist')
})

afterEach(() => resetDocument())

it('Uploads a file', () => {
// Intercept single upload
const { promise, resolve } = Promise.withResolvers<void>()
cy.intercept('PUT', '/remote.php/dav/files/*/*', (req) => {
req.reply({
statusCode: 201,
delay: 2000,
})
req.reply({ statusCode: 201 })
req.on('response', async () => await promise)
}).as('upload')

cy.get('@input').attachFile({
Expand All @@ -95,20 +94,24 @@ describe('UploadPicker valid uploads', () => {
lastModified: new Date().getTime(),
})

cy.get('[data-cy-upload-picker] .upload-picker__progress')
.as('progress')
.should('be.visible')

// Label gets hidden during upload
cy.get('[data-cy-upload-picker]').should('not.have.text', 'New')
cy.get('@progress').should('be.visible')
cy.get('[data-cy-upload-picker]')
.within(() => {
// Label gets hidden during upload
cy.contains('button', 'New').should('not.exist')
// but the button exists
cy.get('button[data-cy-upload-picker-add]')
.should('be.visible')
.and('have.attr', 'aria-label', 'New')
})
.then(() => resolve())

cy.wait('@upload').then(() => {
cy.get('[data-cy-upload-picker] .upload-picker__progress')
.as('progress')
cy.get('@progress')
.should('not.be.visible')

// Label is displayed again after upload
cy.get('[data-cy-upload-picker] button').shouldHaveTrimmedText('New')
cy.get('[data-cy-upload-picker] button').should('contain.text', 'New')
})
})
})
Expand Down
26 changes: 11 additions & 15 deletions cypress/components/UploadPicker/invalid-filenames.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ describe('UploadPicker: invalid filenames (legacy prop)', { testIsolation: true
cy.mount(UploadPicker, { propsData }).as('uploadPicker')

// Label is displayed before upload
cy.get('[data-cy-upload-picker]').shouldHaveTrimmedText('New')
cy.get('[data-cy-upload-picker] [data-cy-upload-picker-add]').should('contain.text', 'New')

// Check and init aliases
cy.get('[data-cy-upload-picker] [data-cy-upload-picker-input]').as('input').should('exist')
Expand Down Expand Up @@ -193,11 +193,11 @@ describe.only('UploadPicker: invalid filenames (server capabilities)', { testIso
cy.mount(UploadPicker, { propsData }).as('uploadPicker')

// Label is displayed before upload
cy.get('[data-cy-upload-picker]').shouldHaveTrimmedText('New')
cy.get('[data-cy-upload-picker] [data-cy-upload-picker-add]').should('contain.text', 'New')

// Check and init aliases
cy.get('[data-cy-upload-picker] [data-cy-upload-picker-input]').as('input').should('exist')
cy.get('[data-cy-upload-picker] .upload-picker__progress').as('progress').should('exist')
cy.get('[data-cy-upload-picker] [data-cy-upload-picker-progress]').as('progress').should('exist')

// Upload
cy.get('@input').attachFile({
Expand All @@ -208,8 +208,7 @@ describe.only('UploadPicker: invalid filenames (server capabilities)', { testIso
lastModified: new Date().getTime(),
})

cy.get('[data-cy-upload-picker] .upload-picker__progress')
.as('progress')
cy.get('@progress')
.should('not.be.visible')

cy.contains('[role="dialog"]', 'Invalid filename')
Expand All @@ -234,11 +233,11 @@ describe.only('UploadPicker: invalid filenames (server capabilities)', { testIso
cy.mount(UploadPicker, { propsData }).as('uploadPicker')

// Label is displayed before upload
cy.get('[data-cy-upload-picker]').shouldHaveTrimmedText('New')
cy.get('[data-cy-upload-picker] [data-cy-upload-picker-add]').should('contain.text', 'New')

// Check and init aliases
cy.get('[data-cy-upload-picker] [data-cy-upload-picker-input]').as('input').should('exist')
cy.get('[data-cy-upload-picker] .upload-picker__progress').as('progress').should('exist')
cy.get('[data-cy-upload-picker] [data-cy-upload-picker-progress]').as('progress').should('exist')

// Upload
cy.get('@input').attachFile({
Expand All @@ -249,8 +248,7 @@ describe.only('UploadPicker: invalid filenames (server capabilities)', { testIso
lastModified: new Date().getTime(),
})

cy.get('[data-cy-upload-picker] .upload-picker__progress')
.as('progress')
cy.get('@progress')
.should('not.be.visible')

cy.contains('[role="dialog"]', 'Invalid filename')
Expand All @@ -275,11 +273,11 @@ describe.only('UploadPicker: invalid filenames (server capabilities)', { testIso
cy.mount(UploadPicker, { propsData }).as('uploadPicker')

// Label is displayed before upload
cy.get('[data-cy-upload-picker]').shouldHaveTrimmedText('New')
cy.get('[data-cy-upload-picker] [data-cy-upload-picker-add]').should('contain.text', 'New')

// Check and init aliases
cy.get('[data-cy-upload-picker] [data-cy-upload-picker-input]').as('input').should('exist')
cy.get('[data-cy-upload-picker] .upload-picker__progress').as('progress').should('exist')
cy.get('[data-cy-upload-picker] [data-cy-upload-picker-progress]').as('progress').should('exist')

// Upload
cy.get('@input').attachFile({
Expand All @@ -290,8 +288,7 @@ describe.only('UploadPicker: invalid filenames (server capabilities)', { testIso
lastModified: new Date().getTime(),
})

cy.get('[data-cy-upload-picker] .upload-picker__progress')
.as('progress')
cy.get('@progress')
.should('not.be.visible')

cy.contains('[role="dialog"]', 'Invalid filename')
Expand Down Expand Up @@ -390,8 +387,7 @@ describe.only('UploadPicker: invalid filenames (server capabilities)', { testIso
lastModified: new Date().getTime(),
}])

cy.get('[data-cy-upload-picker] .upload-picker__progress')
.as('progress')
cy.get('@progress')
.should('not.be.visible')

cy.contains('[role="dialog"]', 'Invalid filename')
Expand Down
52 changes: 42 additions & 10 deletions cypress/components/UploadPicker/progress.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,45 @@ describe('UploadPicker: progress handling', () => {
cy.get('[data-cy-upload-picker] [data-cy-upload-picker-progress-label]').as('progressLabel').should('exist')
})

it('has increasing progress bar during non-chunked upload', () => {
// Start in paused mode
const uploader = getUploader()
it('has upload speed information', () => {
cy.get('@input').attachFile({
// file of 9 MiB
fileContent: new Blob([new ArrayBuffer(9 * 1024 * 1024)]),
fileName: 'file.txt',
mimeType: 'text/plain',
encoding: 'utf8',
lastModified: new Date().getTime(),
})

cy.intercept('PUT', '/remote.php/dav/files/user/file.txt', { statusCode: 201 })

// 128 KB/s
throttleUpload(128 * 1024)

// See there is no progress yet
cy.get('@progress')
.should('be.visible')
.should('have.value', 0)
cy.get('@progressLabel')
.should('contain.text', 'paused')
// start the uploader
.then(() => getUploader().start())

// See the upload has started
cy.get('@progressLabel', { timeout: 10000 })
.should((el) => expect(el.text()).to.match(/\d+(\.\d+)?\s?KB∕s/))
// increase speed to 1MiB/s
.then(() => throttleUpload(1024 * 1024))
cy.get('@progressLabel')
.children('span')
.first({ timeout: 9000 })
.should((el) => {
expect(el.text().trim()).to.equal('a few seconds left')
expect(el.attr('title')).to.match(/\d+(\.\d+)?\s?KB∕s/)
})
})

it('has increasing progress bar during non-chunked upload', () => {
cy.get('@input').attachFile({
// file of 5 MiB
fileContent: new Blob([new ArrayBuffer(5 * 1024 * 1024)]),
Expand Down Expand Up @@ -106,7 +141,7 @@ describe('UploadPicker: progress handling', () => {
cy.get('@progressLabel')
.should('contain.text', 'paused')
// start the uploader
.then(() => uploader.start())
.then(() => getUploader().start())

// See the upload has started
cy.get('@progressLabel')
Expand Down Expand Up @@ -150,9 +185,6 @@ describe('UploadPicker: progress handling', () => {
rq.reply({ statusCode: 201 })
}).as('move')

// Start in paused mode
const uploader = getUploader()

// 3 MiB/s meaning upload will take 5 seconds
throttleUpload(3 * 1024 * 1024)

Expand All @@ -172,7 +204,7 @@ describe('UploadPicker: progress handling', () => {
cy.get('@progressLabel')
.should('contain.text', 'paused')
// start the uploader
.then(() => uploader.start())
.then(() => getUploader().start())

// See the upload has started
cy.get('@progressLabel')
Expand All @@ -197,10 +229,10 @@ describe('UploadPicker: progress handling', () => {

cy.get('@progress')
.should('have.value', 90)
// Now the upload (sending) is done - if we trigger the resolve the value will increase to 97% (or 95 if we resolve only chunk2)
// Now the upload (sending) is done - if we trigger the resolve the value will increase to 96% (or 95 if we resolve only chunk2)
.then(() => resolveChunk1())
cy.get('@progress')
.should('have.value', 97)
.should((e) => expect(Math.round(e.val() as number)).to.be.eq(97))
.then(() => resolveChunk2())
// now the progress should be 100 meaning the progress bar is hidden
cy.get('@progress')
Expand Down
3 changes: 0 additions & 3 deletions cypress/cypress.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,6 @@ declare global {
namespace Cypress {
interface Chainable {
mount: typeof mount
shouldHaveTrimmedText: (
text: string
) => Chainable<JQuery<HTMLElement>>
}
}
}
9 changes: 0 additions & 9 deletions cypress/support/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,3 @@
// https://on.cypress.io/custom-commands
// ***********************************************
import 'cypress-file-upload'

Cypress.Commands.add(
'shouldHaveTrimmedText',
{ prevSubject: true },
(subject: JQuery<HTMLElement>, text: string) => {
cy.wrap(subject)
.should(element => expect(element.text().trim()).to.equal(text))
},
)
Loading
Loading