.agents/skills/frontend-testing/references/workflow.md
Step-by-step process for systematically testing a directory of source files in Langflow.
List all .ts and .tsx files in the target directory (excluding existing test files):
find src/frontend/src/path/to/directory -name '*.ts' -o -name '*.tsx' | grep -v '__tests__' | grep -v '.test.' | grep -v '.spec.' | sort
Sort files into tiers:
| Tier | Description | Examples |
|---|---|---|
| 1 | Pure functions, constants, types | utils.ts, constants.ts, types.ts |
| 2 | Custom hooks (no UI) | useDebounce.ts, useLocalStorage.ts |
| 3 | Simple presentational components | Badge.tsx, EmptyState.tsx |
| 4 | Stateful components | SearchInput.tsx, FilterPanel.tsx |
| 5 | Store-connected components | NodeToolbar.tsx, SidebarHeader.tsx |
| 6 | Async/API components | FlowList.tsx, GlobalVariablesPage.tsx |
| 7 | Integration components | FlowPage.tsx, ChatView.tsx |
npm test -- --coverage --collectCoverageFrom='src/path/to/directory/**/*.{ts,tsx}' src/path/to/directory/__tests__/
For each source file, starting from Tier 1:
Read the entire source file. Identify:
Create __tests__/SourceFileName.test.tsx (or .test.ts for non-JSX files).
jest.clearAllMocks() and any store resets# Run the single test file
npm test -- src/path/to/__tests__/SourceFileName.test.tsx
# Check coverage for the source file
npm test -- --coverage --collectCoverageFrom='src/path/to/SourceFileName.tsx' src/path/to/__tests__/SourceFileName.test.tsx
Common issues:
jest.mock() for the dependencyact() or use await waitFor()screen.debug() to inspect DOMjest.setup.js -- the module may already be mockedIf coverage is below targets (100% function, >95% branch/line):
After all files in the directory have tests:
npm test -- --testPathPattern="src/path/to/directory"
npm test -- --coverage --collectCoverageFrom='src/path/to/directory/**/*.{ts,tsx}' --testPathPattern="src/path/to/directory"
For each test file, verify:
"should ... when ..." patternIf a mock is not actually needed (the real implementation works in jsdom), remove it. Fewer mocks means more realistic tests.
If multiple test files use the same setup patterns, extract them into a test-utils.tsx file in the __tests__ directory:
// __tests__/test-utils.tsx
import { render, type RenderOptions } from "@testing-library/react";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { MemoryRouter } from "react-router-dom";
function createTestQueryClient() {
return new QueryClient({
defaultOptions: {
queries: { retry: false, gcTime: 0 },
mutations: { retry: false },
},
});
}
export function renderWithProviders(
ui: React.ReactElement,
options?: RenderOptions & { route?: string },
) {
const queryClient = createTestQueryClient();
return render(
<QueryClientProvider client={queryClient}>
<MemoryRouter initialEntries={[options?.route ?? "/"]}>
{ui}
</MemoryRouter>
</QueryClientProvider>,
options,
);
}
Note: The Jest config ignores files named test-utils.tsx via testPathIgnorePatterns.
# Run full test suite to ensure nothing is broken
npm test
# Run with coverage for a summary report
npm run test:coverage
The @/ alias maps to src/frontend/src/. If a module is not resolved, check jest.config.js moduleNameMapper.
The project uses transform-import-meta.js to handle Vite's import.meta.env. If you encounter issues, check that the transform is applied in jest.config.js.
Modules mocked in jest.setup.js are mocked globally. If you need the real implementation in a specific test:
// At the top of your test file, before other imports
jest.unmock("@/stores/darkStore");
Always reset store state in beforeEach:
import useMyStore from "@/stores/myStore";
beforeEach(() => {
useMyStore.setState({
// Reset to initial state
items: [],
loading: false,
});
});