Skip to content

DSM-171: Frontend testing setup using Vitest and Testing Library#73

Open
wtomaszewska wants to merge 11 commits into
s3-browserfrom
feature/DSM-171-integrate-frontend-tests
Open

DSM-171: Frontend testing setup using Vitest and Testing Library#73
wtomaszewska wants to merge 11 commits into
s3-browserfrom
feature/DSM-171-integrate-frontend-tests

Conversation

@wtomaszewska

Copy link
Copy Markdown

Ticket DSM-171

Note: This frontend testing setup is identical to the one implemented in the Hyacinth app.

This PR introduces frontend tests using Vitest, Testing Library, and MSW (Mock Service Worker). The focus is on integration tests that verify component rendering and user interactions (sorting columns).

Updated folder structure

vite-plugin-ruby forcibly sets Vite's root to sourceCodeDir. If the React app's entry point (app/javascript) lives in a different directory than the tests (app/s3browser where the frontend code and tests live), the tests are not picked up correctly. To solve this, I moved all frontend code under app/javascript so that the entry point file, the frontend code, and the tests share the same parent directory.

Test Helpers

  • Setup (src/testing/setup.ts) - global test setup that:
    • Starts MSW server before all tests
    • Resets handlers after each test (automatic cleanup)
    • Closes the MSW server after all tests complete
  • Mock API (src/testing/mock-api.ts)
    • mockApi(method, path, body, status) - registers mock API responses for individual tests
    • Supports the "read" HTTP method, which matches the API client's implementation (the app is currently read-only)
  • Data Generators (src/testing/data-generators.ts) - factory functions for creating test data
  • Test Utilities (src/testing/test-utils.tsx)
    • renderApp(ui, options) - renders a component inside QueryClientProvider + MemoryRouter for testing route components

Frontend Tests

Frontend tests cover all the routes users can navigate to.

  • bucket-contents.test.tsx
  • buckets.test.tsx
  • object-details.test.tsx

Note: Pagination tests are not included, as the underlying bugs need to be addressed before we start adding tests.

…ettier on routes and entrypoints subdirectories
…pp for testing components with RQ, add bucket data generator
…frontend tests not being recognized by vitest; adjust paths for linting and formatting
…onsumed; add tests for ObjectDetailsRoute - test object overview and storage details displays; add BucketContentsRoute tests
…ractions; add bucket contents test to verify column sorting; extract app rendering and loader check to renderAppAndWait
@wtomaszewska wtomaszewska requested a review from goldsmithb June 5, 2026 16:07

@goldsmithb goldsmithb left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great! I just left one small suggestion

const routePath = path ?? url; // defaults to url — only pass path for parameterized routes

const router = createMemoryRouter([{ path: routePath, element: ui }], {
initialEntries: url ? ['/', url] : ['/'],

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since url has a default value of '/' and is always truthy, perhaps this could be simplified to just:

initialEntries: ['/', url],
initialIndex: 1,

though it would have a redundant entry if the url is root (but I don't think it would be consequential).

Or something like:

const isRoot = url === '/';
const router = createMemoryRouter([{ path: routePath, element: ui }], {
    initialEntries: isRoot ? ['/'] : ['/', url],
    initialIndex: isRoot ? 0 : 1,
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants