backend
FreeBackend Java — Spring Boot controllers/services, JUnit controller tests, MakeMe. Read this first for any backend work. Use when working on the Java Spring backend.
The English summary is being prepared. Showing the original description.
Frontend Vitest browser-mode tests, Testing Library queries, mockSdkService, makeMe builders, deterministic Vue component testing. Use when writing or changing frontend Vitest tests.
The English summary is being prepared. Showing the original description.
Run score Not tested
See how to installReview the instructions the agent will receive before you install.
Style ("small test" practice — stable boundary, data over mocks, focused assertions, concise makeMe): the unit-testing skill — follow that first.
These commands cover behavioral testing only. Before accepting frontend proof,
also pass the typecheck required by the frontend skill's "Frontend proof" rule.
From the repo root:
CURSOR_DEV=true nix develop -c pnpm frontend:test
All frontend unit-test commands use headless Chromium and never automatically open a browser window. Do not enable a visible browser unless the user explicitly asks.
The legacy UI command also runs headlessly:
CURSOR_DEV=true nix develop -c pnpm frontend:test:ui
Run tests in headless watch mode (the Vitest UI remains available at its printed URL without opening a browser):
CURSOR_DEV=true nix develop -c pnpm frontend:test:watch
Run a single test file from the repo root:
CURSOR_DEV=true nix develop -c pnpm frontend:test tests/path/to/TestFile.spec.ts
Or only the frontend package:
CURSOR_DEV=true nix develop -c pnpm -C frontend test tests/path/to/TestFile.spec.ts
Run a specific test case:
CURSOR_DEV=true nix develop -c pnpm -C frontend test -t "test name pattern"
The test file path is relative to frontend/. Do not use pnpm ... test -- tests/...; the -- is forwarded to Vitest and file filtering is skipped.
In most situations, run all unit tests instead of a selected file only. Use a single test file when actively debugging or iterating on a specific component.
For dough-test-optimization, frontend:test remains the ordinary local
feedback measurement because it runs Chromium browser mode. When per-test JSON
durations are needed for investigation, use
CURSOR_DEV=true nix develop -c pnpm -C frontend exec vitest run --reporter=json.
That plain Vitest run is profiling evidence only; verify retained changes with
the normal browser-mode command and do not compare its wall time directly with
frontend:test.
unit-testing skill); cover lower layers with realistic makeMe props/state, not by testing internal helpers in isolation.data-testid for test selectors.vi.mock is limited to these modules; everything else in-process runs for real:
@/managedApi/AiReplyEventSource: the streaming backend API (same boundary as mockSdkService).@/models/audio/audioRecorder, @/models/audio/recorderWorklet, @/models/wakeLocker: microphone, audio worklet, and screen wake lock, which headless Chromium lacks.file-saver: starts a browser download.pdfjs-dist (gesture-zoom support file only): the PDF engine and worker, whose page geometry the spec must control.Real in-process code, observed through shared helpers:
usePopups stack, emptied before each test; answer and inspect with @tests/helpers/popupStackTestSupport.productionRouterAt(location) and countHistoryEntriesAdded(router) from @tests/helpers; assert the router's current named location.showToastsOnPage() from @tests/helpers/toastTestSupport; assert the toast on the page.Navigation assertions use named locations (or helpers that return them).
Rendered-href assertions use noteShowHref. Path strings belong only in
routes.spec.ts (matching / redirects) and inbound URL classifiers. Test
routers that resolve named screen locations use production routes or
dummyRouteRecordsFromMetadata (the routeMetadata table with dummy
components; no page imports). A spec's router over production routes
comes from productionRouterAt(location) (from @tests/helpers) or plain
withRouter(); every test starts at the root location, reset in shared test
setup. Catch-all / or /:pathMatch(.*)* routers
and useRoute stubs with path: "/" are not a second screen dialect
(ADR 0005).
getByRole, findByRole, queryByRole, getAllByRole, and similar queries; they are slow due to expensive visibility checks.getByText, getByLabelText, getByTitle, or querySelector / querySelectorAll.The backend HTTP API is an external dependency from the frontend’s perspective (unit-testing skill mocking exception).
mockSdkService from @tests/helpers for type-safe mocking: pass the generated controller class and the method name (same static methods as @generated/donut-backend-api/sdk.gen).{ data, error, request, response }.wrapSdkResponse when updating mock return values.mockSdkServiceWithImplementation only for custom async logic based on options.makeMe; do not mock in-process collaborators to “reach” coverage.import { NoteController } from "@generated/donut-backend-api/sdk.gen"
import { mockSdkService } from "@tests/helpers"
beforeEach(() => {
mockSdkService(NoteController, "getRecentNotes", [])
mockSdkService(NoteController, "showNote", makeMe.aNoteRealm.please())
})
import { NoteController } from "@generated/donut-backend-api/sdk.gen"
import { mockSdkService, wrapSdkResponse } from "@tests/helpers"
const spy = mockSdkService(NoteController, "showNote", makeMe.aNoteRealm.please())
spy.mockResolvedValue(wrapSdkResponse(differentNote))
import { TextContentController } from "@generated/donut-backend-api/sdk.gen"
import { mockSdkServiceWithImplementation } from "@tests/helpers"
mockSdkServiceWithImplementation(TextContentController, "updateNoteContent", async (options) => {
return await someAsyncOperation(options)
})
helper.component(ComponentName).withStorageProps if the component requires a storageAccessor prop.withProps instead of withStorageProps if the component does not require storageAccessor.const wrapper = helper
.component(Component)
.withStorageProps({ value: initialValue })
.mount()
await wrapper.setProps({ value: newValue })
makeMe for API-shaped test data; implementation lives in packages/donut-test-fixtures.donut-test-fixtures/makeMe only. Do not import the bare package name or deep paths into src/.unit-testing skill.const note = makeMe.aNoteRealm.title("Dummy Title").content("Description").please()
const answered = makeMe.anAnsweredQuestion
.accidentalMatch("alias", [note.note.noteTopology])
.please()
render() from @testing-library/vue for most tests.render() encourages user-perspective tests and returns fast queries such as getByText, getByLabelText, and data-testid.mount() from @vue/test-utils only when you need direct access to Vue internals, emitted events, slots, or provide/inject edge cases.Prefer:
page.getByText(/submit/i)
screen.getByText("Loading...")
Avoid:
wrapper.findComponent(MyButton)
wrapper.find("[data-testid='my-component']")
scrollWidth <= clientWidth, and range or element rectangles inside their row. Checking textContent alone misses clipped text.page.viewport for breakpoint (sm:) behavior; the default viewport is 414px wide.*.touch.spec.ts when it needs a real coarse pointer. The chromium-touch browser instance in vitest.config.ts runs those files with touch emulation, so (pointer: coarse) matches. Do not substitute a matchMedia stub.Avoid:
if (vm.searchResults) {
const selected = vm.searchResults.find((result) => result.id === wikidataId)
if (selected) {
// do something
}
}
Prefer:
expect(vm.searchResults).toBeDefined()
expect(vm.searchResults.length).toBeGreaterThan(0)
const selected = vm.searchResults.find((result) => result.id === wikidataId)
expect(selected).toBeDefined()
No reviews yet. Tell others what you thought.
No login needed. Share how it worked for you, ask a question, or note where it did not run.
No comments yet. Be the first to write one.
Backend Java — Spring Boot controllers/services, JUnit controller tests, MakeMe. Read this first for any backend work. Use when working on the Java Spring backend.
The English summary is being prepared. Showing the original description.
Backend Java production code, Spring Boot controllers/services/repositories, controller return values, imports, schema ERD pointer. Use when editing backend production Java.
The English summary is being prepared. Showing the original description.
Backend Java tests, controller-level stable-boundary tests, JUnit, @Nested, MakeMe builders, @Transactional, parameterized tests. Use when writing or changing backend JUnit tests.
The English summary is being prepared. Showing the original description.
related to donut CLI. Use when working on donut-cli.
The English summary is being prepared. Showing the original description.
Set up and run the Donut dev environment on Cursor Cloud VM (no Nix). Use when working on Cloud VM, running tests on Cloud VM, or encountering command errors related to missing nix. Triggers on: cloud VM, cloud agent, no nix available, /workspace path.
The English summary is being prepared. Showing the original description.
Regenerate docs/database-erd.md from MySQL information_schema (Mermaid ERD: foreign keys and key columns). Use after Flyway schema changes, new migrations, or when the diagram is stale. Triggers on: database ERD, database-erd.md, export_database_erd, schema diagram, ER diagram after migration.
The English summary is being prepared. Showing the original description.