From 01daf98518c9fbf9fa7ef66361e37d2dab3f9e61 Mon Sep 17 00:00:00 2001 From: Murderlon Date: Tue, 26 Apr 2022 10:49:37 +0200 Subject: [PATCH 1/8] Add test for error events when upload fails --- .eslintrc.js | 2 +- e2e/cypress/integration/dashboard-tus.spec.ts | 23 +++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/.eslintrc.js b/.eslintrc.js index a4b636b1e1..a87304ec18 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -415,7 +415,7 @@ module.exports = { }, { files: ['e2e/**/*.ts', 'e2e/**/*.js'], - rules: { 'import/no-extraneous-dependencies': 'off' }, + rules: { 'import/no-extraneous-dependencies': 'off', 'no-unused-expressions': 'off' }, }, ], } diff --git a/e2e/cypress/integration/dashboard-tus.spec.ts b/e2e/cypress/integration/dashboard-tus.spec.ts index 8bbd16a437..7ce61bbebc 100644 --- a/e2e/cypress/integration/dashboard-tus.spec.ts +++ b/e2e/cypress/integration/dashboard-tus.spec.ts @@ -40,6 +40,29 @@ describe('Dashboard with Tus', () => { }) }) + it('should emit `error` and `upload-error` events on failed POST request', () => { + cy.get('@file-input').attachFile(['images/cat.jpg', 'images/traffic.jpg']) + + const error = cy.spy() + const uploadError = cy.spy() + cy.window().then(({ uppy }) => { + uppy.on('upload-error', uploadError) + uppy.on('error', error) + }) + + cy.get('.uppy-StatusBar-actionBtn--upload').click() + + cy.intercept( + { method: 'POST', pathname: '/files', times: 1 }, + { statusCode: 401, body: { code: 401, message: 'Expired JWT Token' } }, + ).as('patch') + + cy.wait('@patch').then(() => { + expect(error).to.be.called + expect(uploadError).to.be.called + }) + }) + it('should upload remote image with URL plugin', () => { cy.get('[data-cy="Url"]').click() cy.get('.uppy-Url-input').type('https://via.placeholder.com/600x400') From 3921e9a747562ddd25391aa7bc5076b2a1db8ef6 Mon Sep 17 00:00:00 2001 From: Murderlon Date: Tue, 26 Apr 2022 11:24:55 +0200 Subject: [PATCH 2/8] Fix test independence --- e2e/cypress/integration/dashboard-tus.spec.ts | 51 ++++++++++--------- 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/e2e/cypress/integration/dashboard-tus.spec.ts b/e2e/cypress/integration/dashboard-tus.spec.ts index 7ce61bbebc..ec586b4d7d 100644 --- a/e2e/cypress/integration/dashboard-tus.spec.ts +++ b/e2e/cypress/integration/dashboard-tus.spec.ts @@ -4,6 +4,9 @@ type Tus = BaseTus & { requests: { isPaused: boolean } } +// NOTE: we have to use different files to upload per test +// because we are uploading to https://tusd.tusdemo.net, +// constantly uploading the same images gives a different cached result (or something). describe('Dashboard with Tus', () => { beforeEach(() => { cy.visit('/dashboard-tus') @@ -13,6 +16,29 @@ describe('Dashboard with Tus', () => { cy.intercept('http://localhost:3020/search/unsplash/*').as('unsplash') }) + it('should emit `error` and `upload-error` events on failed POST request', () => { + cy.get('@file-input').attachFile(['images/traffic.jpg']) + + const error = cy.spy() + const uploadError = cy.spy() + cy.window().then(({ uppy }) => { + uppy.on('upload-error', uploadError) + uppy.on('error', error) + }) + + cy.get('.uppy-StatusBar-actionBtn--upload').click() + + cy.intercept( + { method: 'POST', pathname: '/files', times: 1 }, + { statusCode: 401, body: { code: 401, message: 'Expired JWT Token' } }, + ).as('post') + + cy.wait('@post').then(() => { + expect(error).to.be.called + expect(uploadError).to.be.called + }) + }) + it('should upload cat image successfully', () => { cy.get('@file-input').attachFile('images/cat.jpg') cy.get('.uppy-StatusBar-actionBtn--upload').click() @@ -23,7 +49,7 @@ describe('Dashboard with Tus', () => { }) it('should start exponential backoff when receiving HTTP 429', () => { - cy.get('@file-input').attachFile(['images/cat.jpg', 'images/traffic.jpg']) + cy.get('@file-input').attachFile(['images/baboon.png']) cy.get('.uppy-StatusBar-actionBtn--upload').click() cy.intercept( @@ -40,29 +66,6 @@ describe('Dashboard with Tus', () => { }) }) - it('should emit `error` and `upload-error` events on failed POST request', () => { - cy.get('@file-input').attachFile(['images/cat.jpg', 'images/traffic.jpg']) - - const error = cy.spy() - const uploadError = cy.spy() - cy.window().then(({ uppy }) => { - uppy.on('upload-error', uploadError) - uppy.on('error', error) - }) - - cy.get('.uppy-StatusBar-actionBtn--upload').click() - - cy.intercept( - { method: 'POST', pathname: '/files', times: 1 }, - { statusCode: 401, body: { code: 401, message: 'Expired JWT Token' } }, - ).as('patch') - - cy.wait('@patch').then(() => { - expect(error).to.be.called - expect(uploadError).to.be.called - }) - }) - it('should upload remote image with URL plugin', () => { cy.get('[data-cy="Url"]').click() cy.get('.uppy-Url-input').type('https://via.placeholder.com/600x400') From f4b7b280746003cf8308dababbfb9554fe5f52ab Mon Sep 17 00:00:00 2001 From: Murderlon Date: Tue, 3 May 2022 17:58:00 +0200 Subject: [PATCH 3/8] Increase timeout again --- e2e/cypress.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e/cypress.json b/e2e/cypress.json index 72796c6643..e758cc30d6 100644 --- a/e2e/cypress.json +++ b/e2e/cypress.json @@ -1,4 +1,4 @@ { "baseUrl": "http://localhost:1234", - "defaultCommandTimeout": 8000 + "defaultCommandTimeout": 16000 } From b2308c066cc7c92841109e631aa744037b51fc58 Mon Sep 17 00:00:00 2001 From: Murderlon Date: Tue, 3 May 2022 18:05:20 +0200 Subject: [PATCH 4/8] Fix compressor test --- e2e/cypress/integration/dashboard-compressor.spec.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/e2e/cypress/integration/dashboard-compressor.spec.ts b/e2e/cypress/integration/dashboard-compressor.spec.ts index 8ebfff5510..d14b6c965e 100644 --- a/e2e/cypress/integration/dashboard-compressor.spec.ts +++ b/e2e/cypress/integration/dashboard-compressor.spec.ts @@ -35,10 +35,6 @@ describe('dashboard-compressor', () => { cy.get('.uppy-StatusBar-actionBtn--upload').click() - cy.get('.uppy-Informer p[role="alert"]', { - timeout: 12000, - }).should('be.visible') - cy.window().then(({ uppy }) => { for (const file of uppy.getFiles()) { expect(file.extension).to.equal('webp') From 87ffb9e4067ebd55821d66663a61d04ea0eb7985 Mon Sep 17 00:00:00 2001 From: Murderlon Date: Tue, 3 May 2022 18:18:29 +0200 Subject: [PATCH 5/8] Actually fix compressor test --- e2e/cypress/integration/dashboard-compressor.spec.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/e2e/cypress/integration/dashboard-compressor.spec.ts b/e2e/cypress/integration/dashboard-compressor.spec.ts index d14b6c965e..b5b71ab368 100644 --- a/e2e/cypress/integration/dashboard-compressor.spec.ts +++ b/e2e/cypress/integration/dashboard-compressor.spec.ts @@ -35,6 +35,10 @@ describe('dashboard-compressor', () => { cy.get('.uppy-StatusBar-actionBtn--upload').click() + // random wait unfortunately for compressing the images + // eslint-disable-next-line cypress/no-unnecessary-waiting + cy.wait(3000) + cy.window().then(({ uppy }) => { for (const file of uppy.getFiles()) { expect(file.extension).to.equal('webp') From 50a71b44fc87171e254851d7617e34cec42ed050 Mon Sep 17 00:00:00 2001 From: Murderlon Date: Tue, 3 May 2022 18:40:58 +0200 Subject: [PATCH 6/8] Fix compressor test in the best way possible --- .../integration/dashboard-compressor.spec.ts | 32 +++++++++---------- packages/@uppy/core/types/index.d.ts | 2 ++ 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/e2e/cypress/integration/dashboard-compressor.spec.ts b/e2e/cypress/integration/dashboard-compressor.spec.ts index b5b71ab368..0cc63fb228 100644 --- a/e2e/cypress/integration/dashboard-compressor.spec.ts +++ b/e2e/cypress/integration/dashboard-compressor.spec.ts @@ -14,7 +14,9 @@ function uglierBytes (text) { return Number(text.slice(0, -2)) } - throw new Error(`Not what the computer thinks a human-readable size string look like: ${text}`) + throw new Error( + `Not what the computer thinks a human-readable size string look like: ${text}`, + ) } describe('dashboard-compressor', () => { @@ -33,27 +35,23 @@ describe('dashboard-compressor', () => { sizeBeforeCompression.push(uglierBytes(text)) }) - cy.get('.uppy-StatusBar-actionBtn--upload').click() - - // random wait unfortunately for compressing the images - // eslint-disable-next-line cypress/no-unnecessary-waiting - cy.wait(3000) - cy.window().then(({ uppy }) => { - for (const file of uppy.getFiles()) { + uppy.on('preprocess-complete', (file) => { expect(file.extension).to.equal('webp') expect(file.type).to.equal('image/webp') - } - }) - cy.get('.uppy-Dashboard-Item-statusSize').should((elements) => { - expect(elements).to.have.length(sizeBeforeCompression.length) + cy.get('.uppy-Dashboard-Item-statusSize').should((elements) => { + expect(elements).to.have.length(sizeBeforeCompression.length) + + for (let i = 0; i < elements.length; i++) { + expect(sizeBeforeCompression[i]).to.be.greaterThan( + uglierBytes(elements[i].textContent), + ) + } + }) + }) - for (let i = 0; i < elements.length; i++) { - expect(sizeBeforeCompression[i]).to.be.greaterThan( - uglierBytes(elements[i].textContent), - ) - } + cy.get('.uppy-StatusBar-actionBtn--upload').click() }) }) }) diff --git a/packages/@uppy/core/types/index.d.ts b/packages/@uppy/core/types/index.d.ts index 71bcf1597f..f34b200e0b 100644 --- a/packages/@uppy/core/types/index.d.ts +++ b/packages/@uppy/core/types/index.d.ts @@ -210,6 +210,7 @@ export type FilesAddedCallback = (files: UppyFile[]) => void; export type FileRemovedCallback = (file: UppyFile, reason: FileRemoveReason) => void; export type UploadCallback = (data: { id: string, fileIDs: string[] }) => void; export type ProgressCallback = (progress: number) => void; +export type PreProcessCompleteCallback = (file: UppyFile) => void; export type UploadProgressCallback = (file: UppyFile, progress: FileProgress) => void; export type UploadSuccessCallback = (file: UppyFile, response: SuccessResponse) => void export type UploadCompleteCallback = (result: UploadResult) => void @@ -225,6 +226,7 @@ export interface UppyEventMap> { 'file-removed': FileRemovedCallback 'upload': UploadCallback 'progress': ProgressCallback + 'preprocess-complete': PreProcessCompleteCallback 'upload-progress': UploadProgressCallback 'upload-success': UploadSuccessCallback 'complete': UploadCompleteCallback From ad59e244950f45f616323322347bc9c3ae8d7be5 Mon Sep 17 00:00:00 2001 From: Murderlon Date: Wed, 4 May 2022 11:17:59 +0200 Subject: [PATCH 7/8] Try something --- e2e/cypress/integration/dashboard-tus.spec.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/e2e/cypress/integration/dashboard-tus.spec.ts b/e2e/cypress/integration/dashboard-tus.spec.ts index ec586b4d7d..6b561aaed2 100644 --- a/e2e/cypress/integration/dashboard-tus.spec.ts +++ b/e2e/cypress/integration/dashboard-tus.spec.ts @@ -16,7 +16,7 @@ describe('Dashboard with Tus', () => { cy.intercept('http://localhost:3020/search/unsplash/*').as('unsplash') }) - it('should emit `error` and `upload-error` events on failed POST request', () => { + it.only('should emit `error` and `upload-error` events on failed POST request', () => { cy.get('@file-input').attachFile(['images/traffic.jpg']) const error = cy.spy() @@ -29,7 +29,7 @@ describe('Dashboard with Tus', () => { cy.get('.uppy-StatusBar-actionBtn--upload').click() cy.intercept( - { method: 'POST', pathname: '/files', times: 1 }, + { method: 'POST', url: 'https://tusd.tusdemo.net/*', times: 1 }, { statusCode: 401, body: { code: 401, message: 'Expired JWT Token' } }, ).as('post') From 1452644b78584c26a56bcba22f0a4d46ab1ee4fb Mon Sep 17 00:00:00 2001 From: Antoine du Hamel Date: Wed, 4 May 2022 11:46:15 +0200 Subject: [PATCH 8/8] Bump Cypress version --- yarn.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/yarn.lock b/yarn.lock index 20b8a77094..7b4f5646ca 100644 --- a/yarn.lock +++ b/yarn.lock @@ -16643,8 +16643,8 @@ __metadata: linkType: hard "cypress@npm:^9.0.0": - version: 9.5.2 - resolution: "cypress@npm:9.5.2" + version: 9.6.0 + resolution: "cypress@npm:9.6.0" dependencies: "@cypress/request": ^2.88.10 "@cypress/xvfb": ^1.2.4 @@ -16678,7 +16678,7 @@ __metadata: listr2: ^3.8.3 lodash: ^4.17.21 log-symbols: ^4.0.0 - minimist: ^1.2.5 + minimist: ^1.2.6 ospath: ^1.2.2 pretty-bytes: ^5.6.0 proxy-from-env: 1.0.0 @@ -16690,7 +16690,7 @@ __metadata: yauzl: ^2.10.0 bin: cypress: bin/cypress - checksum: d19a183df25adcb87ba4914fb177a2b8bf2f004c8364fa21abb6bf66f2462d6f586bf09b58480e804f6b499281d931712a3e262f09880859e3170d513c5c9227 + checksum: 1e5142885a3fb54db6ef7477e3b11b363f1f610ff008982af014e6df3261ac3899f4cad407c598fb690f93029634adb4ad4605929d10776f92175a3eebb471c4 languageName: node linkType: hard