From aab76c4fb0495bf2d940dd1aa446795c08bca59e Mon Sep 17 00:00:00 2001 From: prakash Date: Tue, 21 Jul 2026 22:03:12 +0530 Subject: [PATCH] add tests and mocks --- .../src/GlobalSearch.browser.test.ts | 95 +++++++++++++++++++ .../dashboard/src/mocks/CompanionHandler.ts | 49 +++++++++- 2 files changed, 143 insertions(+), 1 deletion(-) diff --git a/packages/@uppy/dashboard/src/GlobalSearch.browser.test.ts b/packages/@uppy/dashboard/src/GlobalSearch.browser.test.ts index 449d4d239..e35956c73 100644 --- a/packages/@uppy/dashboard/src/GlobalSearch.browser.test.ts +++ b/packages/@uppy/dashboard/src/GlobalSearch.browser.test.ts @@ -5,6 +5,10 @@ import Dropbox from '@uppy/dropbox' import GoogleDrive from '@uppy/google-drive' import { afterAll, afterEach, beforeAll, describe, expect, test } from 'vitest' import { page, userEvent } from 'vitest/browser' +import { + LONG_PROVIDER_FILE_NAME, + LONG_PROVIDER_FOLDER_NAME, +} from './mocks/CompanionHandler.js' import { worker } from './setup.js' import '@uppy/core/css/style.css' @@ -74,6 +78,97 @@ afterEach(async () => { }) describe('ProviderView Search E2E', () => { + test('long provider names stay within the Dashboard', async () => { + uppy = initializeUppy(['Dropbox']) + + await expect + .element(page.getByRole('presentation').getByText('Dropbox')) + .toBeVisible() + await page.getByRole('tab', { name: 'Dropbox' }).click() + + for (const folderName of [ + 'first', + 'second', + 'third', + LONG_PROVIDER_FOLDER_NAME, + ]) { + const folder = page.getByRole('button', { name: folderName }) + await expect.element(folder).toBeVisible() + await folder.click() + } + + await expect + .element( + page.getByRole('checkbox', { + name: LONG_PROVIDER_FILE_NAME, + exact: true, + }), + ) + .toBeVisible() + + const panelBody = document.querySelector( + '.uppy-DashboardContent-panelBody', + ) as HTMLElement + const provider = document.querySelector( + '.uppy-ProviderBrowser', + ) as HTMLElement + const list = document.querySelector( + '.uppy-ProviderBrowser-list', + ) as HTMLElement + const breadcrumb = document.querySelector( + '.uppy-Provider-breadcrumbs', + ) as HTMLElement + const currentBreadcrumb = breadcrumb.querySelector( + 'button:last-of-type', + ) as HTMLButtonElement + const logout = document.querySelector( + '.uppy-ProviderBrowser-userLogout', + ) as HTMLElement + const longFileLabel = Array.from( + document.querySelectorAll('.uppy-ProviderBrowserItem-inner'), + ).find( + (item) => item.textContent === LONG_PROVIDER_FILE_NAME, + ) as HTMLElement + const longFilename = longFileLabel.querySelector( + '.uppy-truncate-text', + ) as HTMLElement + + const panelRect = panelBody.getBoundingClientRect() + const providerRect = provider.getBoundingClientRect() + const listRect = list.getBoundingClientRect() + const breadcrumbRect = breadcrumb.getBoundingClientRect() + const currentBreadcrumbRect = currentBreadcrumb.getBoundingClientRect() + const logoutRect = logout.getBoundingClientRect() + const filenameRect = longFilename.getBoundingClientRect() + + expect(providerRect.width).toBeLessThanOrEqual(panelRect.width) + expect(providerRect.right).toBeLessThanOrEqual(panelRect.right) + expect(listRect.width).toBeLessThanOrEqual(panelRect.width) + expect(listRect.right).toBeLessThanOrEqual(panelRect.right) + expect(Math.abs(listRect.right - providerRect.right)).toBeLessThanOrEqual(1) + + expect(list.scrollHeight).toBeGreaterThan(list.clientHeight) + list.scrollTop = 40 + expect(list.scrollTop).toBeGreaterThan(0) + + expect(longFilename.scrollWidth).toBeGreaterThan(longFilename.clientWidth) + expect(filenameRect.right).toBeLessThanOrEqual(listRect.right) + expect(getComputedStyle(longFilename).textOverflow).toBe('ellipsis') + + expect(currentBreadcrumb.scrollWidth).toBeGreaterThan( + currentBreadcrumb.clientWidth, + ) + expect(currentBreadcrumb.clientWidth).toBeGreaterThan(0) + expect(currentBreadcrumbRect.right).toBeLessThanOrEqual( + breadcrumbRect.right, + ) + expect(getComputedStyle(currentBreadcrumb).textOverflow).toBe('ellipsis') + expect(logoutRect.right).toBeLessThanOrEqual(providerRect.right) + await expect + .element(page.getByRole('button', { name: 'Log out' })) + .toBeVisible() + }) + test('Search for nested file in Dropbox and verify results', async () => { uppy = initializeUppy(['Dropbox']) await expect diff --git a/packages/@uppy/dashboard/src/mocks/CompanionHandler.ts b/packages/@uppy/dashboard/src/mocks/CompanionHandler.ts index ced245cbc..c929c6ff1 100644 --- a/packages/@uppy/dashboard/src/mocks/CompanionHandler.ts +++ b/packages/@uppy/dashboard/src/mocks/CompanionHandler.ts @@ -2,6 +2,14 @@ import { HttpResponse, http } from 'msw' const COMPANION_URL = 'http://companion.test' +export const LONG_PROVIDER_FOLDER_NAME = + 'ThisFolderNameIsIntentionallyLongAndUnbrokenSoThatItCannotFitInsideTheProviderBreadcrumbWithoutBeingTruncated' + +const LONG_PROVIDER_FOLDER_PATH = `/first/second/third/${LONG_PROVIDER_FOLDER_NAME}` +const LONG_PROVIDER_FILE_NAME_PREFIX = + 'ThisFileNameIsIntentionallyLongAndUnbrokenSoThatItCannotFitInsideTheProviderFileListWithoutBeingTruncated' +export const LONG_PROVIDER_FILE_NAME = `${LONG_PROVIDER_FILE_NAME_PREFIX}01.pdf` + /** * Mocked Folder structure : * @@ -11,7 +19,9 @@ root/ (Dropbox) │ ├── second/ │ │ ├── third/ │ │ │ ├── nested-target.pdf -│ │ │ └── new-file.pdf +│ │ │ ├── new-file.pdf +│ │ │ └── ThisFolderNameIsIntentionallyLongAndUnbroken.../ +│ │ │ └── ThisFileNameIsIntentionallyLongAndUnbroken...01-24.pdf │ │ ├── deep-file.txt │ │ ├── target.pdf │ │ └── workspace.pdf @@ -203,11 +213,48 @@ export const handlers = [ modifiedDate: '2024-01-10T00:00:00Z', size: 3072, }, + { + isFolder: true, + icon: 'folder', + name: LONG_PROVIDER_FOLDER_NAME, + mimeType: 'folder', + id: 'folder-long-provider-name', + thumbnail: null, + requestPath: encodeURIComponent(LONG_PROVIDER_FOLDER_PATH), + modifiedDate: '2024-01-12T00:00:00Z', + size: null, + }, ], nextPagePath: null, }) } + // Long folder with enough long-named files to exercise truncation and scrolling + if (pathStr === LONG_PROVIDER_FOLDER_PATH) { + return HttpResponse.json({ + username: 'test-user@example.com', + items: Array.from({ length: 24 }, (_, index) => { + const sequence = String(index + 1).padStart(2, '0') + const name = `${LONG_PROVIDER_FILE_NAME_PREFIX}${sequence}.pdf` + + return { + isFolder: false, + icon: 'file', + name, + mimeType: 'application/pdf', + id: `file-long-provider-name-${sequence}`, + thumbnail: null, + requestPath: encodeURIComponent( + `${LONG_PROVIDER_FOLDER_PATH}/${name}`, + ), + modifiedDate: '2024-01-13T00:00:00Z', + size: 4096 + index, + } + }), + nextPagePath: null, + }) + } + // workspace folder if (pathStr === '/workspace') { return HttpResponse.json({