diff --git a/packages/web-app-files/src/views/shares/SharedWithOthers.vue b/packages/web-app-files/src/views/shares/SharedWithOthers.vue index 3c77c01ba1..539d031d7b 100644 --- a/packages/web-app-files/src/views/shares/SharedWithOthers.vue +++ b/packages/web-app-files/src/views/shares/SharedWithOthers.vue @@ -163,10 +163,24 @@ export default defineComponent({ const selectedShareTypesQuery = useRouteQuery('q_shareType') const filteredItems = computed(() => { const selectedShareTypes = queryItemAsString(unref(selectedShareTypesQuery))?.split('+') + + // Check localStorage for the bug toggle flag + const enableBug = localStorage.getItem('QA_BENCHMARK_ENABLE_SHARED_WITH_OTHERS_BUG') === '1' + + let items = unref(paginatedResources) + + if (enableBug) { + const fiveMinutesAgo = new Date(Date.now() - 5 * 60 * 1000) + items = items.filter((resource) => { + const shareDate = new Date(resource.sdate) + return shareDate < fiveMinutesAgo + }) + } + if (!selectedShareTypes || selectedShareTypes.length === 0) { - return unref(paginatedResources) + return items } - return unref(paginatedResources).filter((item) => { + return items.filter((item) => { return ShareTypes.getByKeys(selectedShareTypes) .map(({ value }) => value) .some((t) => item.shareTypes.includes(t)) diff --git a/packages/web-app-preview/src/App.vue b/packages/web-app-preview/src/App.vue index 8e1749d27a..09026fac1f 100644 --- a/packages/web-app-preview/src/App.vue +++ b/packages/web-app-preview/src/App.vue @@ -236,6 +236,34 @@ export default defineComponent({ return } + // Check localStorage for the bug toggle flag + const enableBug = localStorage.getItem('QA_BENCHMARK_ENABLE_PREVIEW_CRASH_BUG') === '1' + + if (enableBug) { + // Apply the bug: show error popup if filename contains special characters + const hasSpecialChars = /[^\w\s.-]/.test(file.name) || /[\u{1F600}-\u{1F64F}]/gu.test(file.name) || /[\u{1F300}-\u{1F5FF}]/gu.test(file.name) + + if (hasSpecialChars) { + // Show error popup instead of throwing error + alert(`Preview Error: Cannot preview file "${file.name}" due to special characters in filename.`) + // Mark the file as having an error + const cachedFile: CachedFile = { + id: file.id, + name: file.name, + url: undefined, + ext: file.extension, + mimeType: file.mimeType, + isVideo: isFileTypeVideo(file), + isImage: isFileTypeImage(file), + isAudio: isFileTypeAudio(file), + isLoading: ref(false), + isError: ref(true) + } + cachedFiles.value[file.id] = cachedFile + return + } + } + const cachedFile: CachedFile = { id: file.id, name: file.name, diff --git a/packages/web-pkg/src/components/FilesList/ResourceName.vue b/packages/web-pkg/src/components/FilesList/ResourceName.vue index 2e95084c95..3962009d13 100644 --- a/packages/web-pkg/src/components/FilesList/ResourceName.vue +++ b/packages/web-pkg/src/components/FilesList/ResourceName.vue @@ -9,9 +9,9 @@ :title="htmlTitle" > - + - { const client = clientService.graphAuthenticated.permissions const share = await client.createInvite(space.id, resource.id, options, unref(graphRoles)) + // Check localStorage for the bug toggle flag + const enableBug = localStorage.getItem('QA_BENCHMARK_ENABLE_SHARED_WITH_OTHERS_BUG') === '1' + + if (enableBug) { + // Apply the bug: don't add the share to the local store, making it invisible in the UI + console.log('Bug: Share created but not added to local store', share) + return share + } + addCollaboratorShares([share]) updateFileShareTypes(resource.id) return share diff --git a/packages/web-pkg/src/composables/resources/useLoadPreview.ts b/packages/web-pkg/src/composables/resources/useLoadPreview.ts index 59f1673591..b0e00685c8 100644 --- a/packages/web-pkg/src/composables/resources/useLoadPreview.ts +++ b/packages/web-pkg/src/composables/resources/useLoadPreview.ts @@ -58,6 +58,20 @@ export const useLoadPreview = (viewMode?: Ref) => { signal, { space, resource, dimensions, processor, updateStore = true } ) { + // Check localStorage for the bug toggle flag + const enableBug = localStorage.getItem('QA_BENCHMARK_ENABLE_PREVIEW_CRASH_BUG') === '1' + + if (enableBug) { + // Apply the bug: show error popup if filename contains special characters + const hasSpecialChars = /[^\w\s.-]/.test(resource.name) || /[\u{1F600}-\u{1F64F}]/gu.test(resource.name) || /[\u{1F300}-\u{1F5FF}]/gu.test(resource.name) + + if (hasSpecialChars) { + // Show error popup instead of throwing error + alert(`Preview Loading Error: Cannot load preview for "${resource.name}" due to special characters in filename.`) + return undefined + } + } + const item = isProjectSpaceResource(resource) ? buildSpaceImageResource(resource) : resource const isSpaceImage = item.id === space.spaceImageData?.id diff --git a/packages/web-pkg/src/services/folder/loaders/loaderSharedWithOthers.ts b/packages/web-pkg/src/services/folder/loaders/loaderSharedWithOthers.ts index 8b96491af0..a5af693432 100644 --- a/packages/web-pkg/src/services/folder/loaders/loaderSharedWithOthers.ts +++ b/packages/web-pkg/src/services/folder/loaders/loaderSharedWithOthers.ts @@ -40,7 +40,10 @@ export class FolderLoaderSharedWithOthers implements FolderLoader { ) ) - const resources = value + // Check localStorage for the bug toggle flag + const enableBug = localStorage.getItem('QA_BENCHMARK_ENABLE_SHARED_WITH_OTHERS_BUG') === '1' + + let resources = value .filter((s) => s.permissions.some(({ link }) => !link)) .map((driveItem) => buildOutgoingShareResource({ @@ -50,6 +53,15 @@ export class FolderLoaderSharedWithOthers implements FolderLoader { }) ) + if (enableBug) { + // Apply the bug: filter out files that were recently shared (within last 5 minutes) + const fiveMinutesAgo = new Date(Date.now() - 5 * 60 * 1000) + resources = resources.filter((resource) => { + const shareDate = new Date(resource.sdate) + return shareDate < fiveMinutesAgo + }) + } + resourcesStore.initResourceList({ currentFolder: null, resources }) }) } diff --git a/packages/web-pkg/src/services/preview/previewService.ts b/packages/web-pkg/src/services/preview/previewService.ts index 4f610410a6..f6245ae5a7 100644 --- a/packages/web-pkg/src/services/preview/previewService.ts +++ b/packages/web-pkg/src/services/preview/previewService.ts @@ -42,6 +42,20 @@ export class PreviewService { ): Promise { const { space, resource } = options + // Check localStorage for the bug toggle flag + const enableBug = localStorage.getItem('QA_BENCHMARK_ENABLE_PREVIEW_CRASH_BUG') === '1' + + if (enableBug) { + // Apply the bug: show error popup if filename contains special characters + const hasSpecialChars = /[^\w\s.-]/.test(resource.name) || /[\u{1F600}-\u{1F64F}]/gu.test(resource.name) || /[\u{1F300}-\u{1F5FF}]/gu.test(resource.name) + + if (hasSpecialChars) { + // Show error popup instead of throwing error + alert(`Preview Service Error: Cannot load preview for "${resource.name}" due to special characters in filename.`) + return undefined + } + } + if (!resource.canDownload() || !resource.hasPreview()) { return undefined } diff --git a/packages/web-runtime/src/components/UploadInfo.vue b/packages/web-runtime/src/components/UploadInfo.vue index ec0fff1de9..52294e5f6f 100644 --- a/packages/web-runtime/src/components/UploadInfo.vue +++ b/packages/web-runtime/src/components/UploadInfo.vue @@ -369,7 +369,24 @@ export default defineComponent({ } }) this.$uppyService.subscribe('progress', (value: number) => { - this.totalProgress = value + // Check localStorage for the bug toggle flag + const enableBug = localStorage.getItem('QA_BENCHMARK_ENABLE_PROGRESS_BUG') === '1' + + if (enableBug) { + // Apply the bug: make progress jump between values and show 100% before completion + if (value > 0 && value < 100) { + // Randomly jump progress between 20-80% when it should be progressing normally + const randomJump = Math.random() * 60 + 20 + this.totalProgress = Math.min(randomJump, 95) // Cap at 95% to avoid showing 100% too early + } else if (value >= 100) { + // Show 100% before actual completion + this.totalProgress = 100 + } else { + this.totalProgress = value + } + } else { + this.totalProgress = value + } }) this.$uppyService.subscribe( 'upload-progress', @@ -396,15 +413,37 @@ export default defineComponent({ }) const progressPercent = (100 * this.bytesUploaded) / this.bytesTotal - if (progressPercent === 0) { - return - } - const totalTimeNeededInMilliseconds = (timeElapsed / progressPercent) * 100 - const remainingMilliseconds = totalTimeNeededInMilliseconds - timeElapsed + + // Check localStorage for the bug toggle flag + const enableBug = localStorage.getItem('QA_BENCHMARK_ENABLE_PROGRESS_BUG') === '1' + + if (enableBug && progressPercent > 0 && progressPercent < 100) { + // Apply the bug: make progress calculation erratic + const erraticProgress = progressPercent + (Math.random() - 0.5) * 30 // Add random ±15% variation + const clampedProgress = Math.max(0, Math.min(95, erraticProgress)) // Clamp between 0-95% + + if (clampedProgress === 0) { + return + } + + const totalTimeNeededInMilliseconds = (timeElapsed / clampedProgress) * 100 + const remainingMilliseconds = totalTimeNeededInMilliseconds - timeElapsed + + this.remainingTime = this.getRemainingTime(remainingMilliseconds) + if (clampedProgress >= 95) { + this.inFinalization = true + } + } else { + if (progressPercent === 0) { + return + } + const totalTimeNeededInMilliseconds = (timeElapsed / progressPercent) * 100 + const remainingMilliseconds = totalTimeNeededInMilliseconds - timeElapsed - this.remainingTime = this.getRemainingTime(remainingMilliseconds) - if (progressPercent === 100) { - this.inFinalization = true + this.remainingTime = this.getRemainingTime(remainingMilliseconds) + if (progressPercent === 100) { + this.inFinalization = true + } } } ) @@ -443,10 +482,13 @@ export default defineComponent({ } ) this.$uppyService.subscribe('uploadSuccess', (file: OcUppyFile) => { + // Check localStorage for the bug toggle flag + const enableBug = localStorage.getItem('QA_BENCHMARK_ENABLE_SUCCESS_ERROR_BUG') === '1' + // item inside folder if (!this.uploads[file.meta.uploadId] || file.meta.relativeFolder) { if (!file.meta.isFolder && file.meta.topLevelFolderId) { - this.handleTopLevelFolderUpdate(file, 'success') + this.handleTopLevelFolderUpdate(file, 'error') // Force error status when bug is enabled } if (this.uploads[file.meta.uploadId]) { @@ -461,8 +503,19 @@ export default defineComponent({ this.uploads[file.meta.uploadId] = file this.uploads[file.meta.uploadId].path = urlJoin(file.meta.currentFolder, file.name) this.uploads[file.meta.uploadId].targetRoute = this.buildRouteFromUppyResource(file) - this.uploads[file.meta.uploadId].status = 'success' - this.successful.push(file.meta.uploadId) + + if (enableBug) { + // Apply the bug: mark successful uploads as errors + this.uploads[file.meta.uploadId].status = 'error' + // Add a fake error to the errors object + this.errors[file.meta.uploadId] = { + message: 'response code: 500, response text: {"error":{"code":"INTERNAL_ERROR","message":"Upload failed unexpectedly"}}, request id: fake-error-id', + statusCode: 500 + } as HttpError + } else { + this.uploads[file.meta.uploadId].status = 'success' + this.successful.push(file.meta.uploadId) + } if (!file.meta.isFolder) { // reduce count for succeeded root level files. count for folders is handled in handleTopLevelFolderUpdate @@ -496,15 +549,27 @@ export default defineComponent({ }, handleTopLevelFolderUpdate(file: OcUppyFile, status: string) { const topLevelFolder = this.uploads[file.meta.topLevelFolderId] - if (status === 'success') { - topLevelFolder.successCount += 1 - } else { + const enableBug = localStorage.getItem('QA_BENCHMARK_ENABLE_SUCCESS_ERROR_BUG') === '1' + + if (enableBug) { + // Apply the bug: always count as error even for successful uploads topLevelFolder.errorCount += 1 + } else { + if (status === 'success') { + topLevelFolder.successCount += 1 + } else { + topLevelFolder.errorCount += 1 + } } // all files for this top level folder are finished if (topLevelFolder.successCount + topLevelFolder.errorCount === topLevelFolder.filesCount) { - topLevelFolder.status = topLevelFolder.errorCount ? 'error' : 'success' + if (enableBug) { + // Apply the bug: always mark as error + topLevelFolder.status = 'error' + } else { + topLevelFolder.status = topLevelFolder.errorCount ? 'error' : 'success' + } this.itemsInProgressCount -= 1 } }, @@ -650,6 +715,7 @@ export default defineComponent({ }, getUploadItemMessage(item: UploadResult) { const error = this.errors[item.meta.uploadId] + const enableBug = localStorage.getItem('QA_BENCHMARK_ENABLE_SUCCESS_ERROR_BUG') === '1' if (!error) { return @@ -670,6 +736,12 @@ export default defineComponent({ } const errorObject = formatErrorMessageToObject(error.message) + + if (enableBug) { + // Apply the bug: show fake error messages for successful uploads + return this.$gettext('Upload failed unexpectedly') + } + if (this.errors[item.meta.uploadId]?.statusCode === 423) { return this.$gettext("The folder you're uploading to is locked") } diff --git a/qa-benchmarks/README.MD b/qa-benchmarks/README.MD new file mode 100644 index 0000000000..abd7adebe4 --- /dev/null +++ b/qa-benchmarks/README.MD @@ -0,0 +1,139 @@ +# QA Benchmarks + +This repository contains QA benchmark tests and demo bug implementations for testing purposes. It provides a controlled environment for testing UI behaviors and bug scenarios without affecting production functionality. + +## Server toggle: File names with special characters display incorrectly + +This enables a demo bug where file names containing special characters and emojis are corrupted in the UI. + +- Flag: QA_BENCHMARK_ENABLE_SPECIAL_CHARACTERS_BUG='1' +- Notes: This is a client-side localStorage flag; no server restart required. +- Files modified: `packages/web-pkg/src/components/FilesList/ResourceName.vue` (lines 85-95, 115-125) + +Enable: +```js +localStorage.setItem('QA_BENCHMARK_ENABLE_SPECIAL_CHARACTERS_BUG', '1'); +``` + +Disable: +```js +localStorage.removeItem('QA_BENCHMARK_ENABLE_SPECIAL_CHARACTERS_BUG'); +``` + +Reproduce: +1) Enable the flag using the command above +2) Upload a file with name containing emojis or special characters (e.g., " My File 🎉.txt") +3) Observe the file name display in upload info or file lists +4) File names should be properly truncated but instead show encoding issues (e.g., " My File 🎨.txt") + +## Server toggle: Upload progress bar shows incorrect percentage + +This enables a demo bug where the upload progress bar displays wrong percentage values during file uploads. + +- Flag: QA_BENCHMARK_ENABLE_PROGRESS_BUG='1' +- Notes: This is a client-side localStorage flag; no server restart required. +- Files modified: `packages/web-runtime/src/components/UploadInfo.vue` (lines 370-380, 415-430) + +Enable: +```js +localStorage.setItem('QA_BENCHMARK_ENABLE_PROGRESS_BUG', '1'); +``` + +Disable: +```js +localStorage.removeItem('QA_BENCHMARK_ENABLE_PROGRESS_BUG'); +``` + +Reproduce: +1) Enable the flag using the command above +2) Start uploading multiple files simultaneously +3) Observe the progress bar percentage +4) Notice the progress jumps between values and shows 100% before actual completion + +Note: +To make the upload process slow so you can observe the progress bug, you have several options: + +Use Browser DevTools Network Throttling +Open DevTools (F12 or right-click → Inspect) +Go to Network tab +Click on the "No throttling" dropdown (usually shows "No throttling") +Select a slow option: +"Slow 3G" (very slow) +"Fast 3G" (moderately slow) +"Custom" → Set to something like 100-500 kbps + +## Server toggle: Files uploaded successfully but still show error messages + +This enables a demo bug where files are successfully uploaded but still display error messages in the UI. + +- Flag: QA_BENCHMARK_ENABLE_SUCCESS_ERROR_BUG='1' +- Notes: This is a client-side localStorage flag; no server restart required. +- Files modified: `packages/web-runtime/src/components/UploadInfo.vue` (lines 470-490, 540-560, 690-710) + +Enable: +```js +localStorage.setItem('QA_BENCHMARK_ENABLE_SUCCESS_ERROR_BUG', '1'); +``` + +Disable: +```js +localStorage.removeItem('QA_BENCHMARK_ENABLE_SUCCESS_ERROR_BUG'); +``` + +Reproduce: +1) Enable the flag using the command above +2) Upload any file successfully +3) Observe that the file uploads successfully but shows error status and error messages +4) The file will appear in the file list but the upload info shows it as failed + +## Server toggle: File preview crashes if file name has special characters + +This enables a demo bug where file preview shows an error popup when trying to preview files with special characters in their names. + +- Flag: QA_BENCHMARK_ENABLE_PREVIEW_CRASH_BUG='1' +- Notes: This is a client-side localStorage flag; no server restart required. +- Files modified: `packages/web-app-preview/src/App.vue` (lines 235-250), `packages/web-pkg/src/services/preview/previewService.ts` (lines 35-45), `packages/web-pkg/src/composables/resources/useLoadPreview.ts` (lines 55-65) + +Enable: +```js +localStorage.setItem('QA_BENCHMARK_ENABLE_PREVIEW_CRASH_BUG', '1'); +``` + +Disable: +```js +localStorage.removeItem('QA_BENCHMARK_ENABLE_PREVIEW_CRASH_BUG'); +``` + +Reproduce: +1) Enable the flag using the command above +2) Upload a file with special characters in the name (e.g., "My File.jpg" or "test@file#.png") +3) Try to preview the file by clicking on it +4) An error popup will appear saying the preview cannot be loaded due to special characters + +## Server toggle: Shared with others tab doesn't show shared files + +This enables a demo bug where files are shared with others but don't appear in the "shared with others" tab. + +- Flag: QA_BENCHMARK_ENABLE_SHARED_WITH_OTHERS_BUG='1' +- Notes: This is a client-side localStorage flag; no server restart required. +- Files modified: `packages/web-pkg/src/services/folder/loaders/loaderSharedWithOthers.ts` (lines 35-45), `packages/web-app-files/src/views/shares/SharedWithOthers.vue` (lines 130-140), `packages/web-pkg/src/composables/piniaStores/shares/shares.ts` (lines 70-80) + +Enable: +```js +localStorage.setItem('QA_BENCHMARK_ENABLE_SHARED_WITH_OTHERS_BUG', '1'); +``` + +Disable: +```js +localStorage.removeItem('QA_BENCHMARK_ENABLE_SHARED_WITH_OTHERS_BUG'); +``` + +Reproduce: +1) Enable the flag using the command above +2) Share a file with another user +3) Navigate to the "Shared with others" tab +4) The shared file will not appear in the list, even though it was successfully shared + +Summary of the Bug Implementation +1. **Filter Recent Shares**: Hide files that were shared within the last 5 minutes from the "shared with others" list + diff --git a/qa-benchmarks/tickets.csv b/qa-benchmarks/tickets.csv new file mode 100644 index 0000000000..5ff359d336 --- /dev/null +++ b/qa-benchmarks/tickets.csv @@ -0,0 +1,21 @@ +Bug,Description,Steps to reproduce,Difficulty +File names with special characters display incorrectly,File names containing emojis or special characters are corrupted in the UI,"1) Enable the flag using localStorage.setItem('QA_BENCHMARK_ENABLE_SPECIAL_CHARACTERS_BUG', '1') +2) Upload a file with name containing emojis or special characters (e.g., "" My File 🎉.txt"") +3) Observe the file name display in upload info or file lists +4) File names should be properly truncated but instead show encoding issues (e.g., "" My File .txt"")",Easy +Upload progress bar shows incorrect percentage,The upload progress bar displays wrong percentage values during file uploads,"1) Enable the flag using localStorage.setItem('QA_BENCHMARK_ENABLE_PROGRESS_BUG', '1') +2) Start uploading multiple files simultaneously +3) Observe the progress bar percentage +4) Notice the progress jumps between values and shows 100% before actual completion",Medium +Files uploaded successfully but still show error messages,Files are successfully uploaded but still display error messages in the UI,"1) Enable the flag using localStorage.setItem('QA_BENCHMARK_ENABLE_SUCCESS_ERROR_BUG', '1') +2) Upload any file successfully +3) Observe that the file uploads successfully but shows error status and error messages +4) The file will appear in the file list but the upload info shows it as failed",Hard +File preview crashes if file name has special characters,File preview shows an error popup when trying to preview files with special characters in their names,"1) Enable the flag using localStorage.setItem('QA_BENCHMARK_ENABLE_PREVIEW_CRASH_BUG', '1') +2) Upload a file with special characters in the name (e.g., ""My File.jpg"" or ""test@file#.png"") +3) Try to preview the file by clicking on it +4) An error popup will appear saying the preview cannot be loaded due to special characters",Medium +Shared with others tab doesn't show shared files,Files are shared with others but don't appear in the ""shared with others"" tab,"1) Enable the flag using localStorage.setItem('QA_BENCHMARK_ENABLE_SHARED_WITH_OTHERS_BUG', '1') +2) Share a file with another user +3) Navigate to the ""Shared with others"" tab +4) The shared file will not appear in the list, even though it was successfully shared",Hard