LoadedPlugin
name is the same id the registry stamps on every contribution (pluginId); the
version comes from the plugin’s manifest.
Properties
PluginContributionsSnapshot
usePluginContributions returns: the load status and the registry.
Properties
Related: PluginContributions
PluginLoadInputs
mounts, the
plugin’s own route items and their resolved absolute bases ({item: "/api/<base>"}),
and declaredRoutePanels, the channels its manifest lists under
contributions.route_panels.
Properties
PluginLoaderState
status gates when the
contributions are complete, and the error fields carry the loud failures.
Properties
Related: LoadedPlugin
StaticToolDisplayNamesProvider
reload defaults to a no-op; a test that exercises the
reload wiring passes a spy. Re-exported from the testing entry.
Parameters
Related: ToolDisplayNamesContextValue
__resetContributions
__resetPluginHostState
contributionCovered
Related: RequiredCapabilities
deferred
resolve/reject. It pins a component’s loading state for assertion: hand the
unsettled promise to the code under test (e.g. as a mocked api call’s return
value), assert the in-flight UI while it hangs, then call resolve/reject to
drive the success or failure branch and assert the settled UI. Each call
returns a fresh, independent deferred.
destructiveColorOffences
source that paint text with a destructive role token, in the
order they appear. The destructive tokens are the fill, its hover and the label on
that fill: a fill colour as text fails contrast on the dark grounds, so error text
takes --tai-color-err-text instead. A color declaration (CSS or JSX) is an
offence anywhere but the .tai-btn-danger rule, where the label colour belongs. A
reference whose property cannot be read is reported as <no property found>: an
unattributable declaration is a hole in the rule, not a pass.
Parameters
flushResizeObservers
ResizeObserver stub’s callback for the elements it is
observing. Pair it with setElementOverflow to drive a component that
measures itself (ScrollRegion and useProseScrollRegions re-read
scrollWidth/clientWidth from their observer callbacks):
setElementOverflow(region, true);
flushResizeObservers();
Only meaningful once installJsdomStubs has installed the stub; with a real
ResizeObserver present (a browser environment) there is nothing to flush.
flushResizeObserversFor
flushResizeObservers. Use it to prove which element a
component is watching: a measurement driven by a resize of a CHILD only
arrives if that child is observed, so the assertion fails the moment a
component narrows its observation to its own box.
Parameters
getContributions
getPluginHostState
usePluginContributions reads.
Related: PluginLoaderState
installJsdomStubs
test-setup.ts identical and lets interaction tests exercise the real
components instead of mocking them out:
- Radix primitives observe element size (
ResizeObserver), scroll the active item into view, and capture the pointer while opening. - Export/download paths create and revoke object URLs.
- File-import flows read the picked file via
Blob.text(). - Router scroll restoration calls
scrollToon navigation.
ResizeObserver stub is a WORKING observer, not an inert one: it keeps a
registry of the observers still in use, delivers an entry to the callback as
each element is observed (as a real observer does for its initial
observation), and lets a test re-deliver on demand via
flushResizeObservers. Components that size themselves — ScrollRegion and
useProseScrollRegions — are therefore exercised for real, with
setElementOverflow supplying the scroll metrics jsdom cannot compute.
Each stub only fills a MISSING API, so installing the whole set everywhere is
harmless — the one exception is window.scrollTo, which jsdom ships as a “Not
implemented” stub that logs loudly on every navigation, so it is replaced
unconditionally. Call once from a package’s Vitest setupFiles entry.
loadPlugin
register entry with a context bound to pluginId,
then commit everything it staged into the global registry.
entry is AWAITED before commit, so a synchronous or an async entry is fully
done first: a post-await throw skips the commit (atomicity holds for async too)
and a post-await registration cannot slip past the batch. The seal is set after
entry has SETTLED, so a later registration throws loudly; registrations made
during entry’s synchronous body — including a microtask it enqueues then — are
still captured and committed. A register that throws commits nothing.
Parameters
Related: PluginEntry, PluginLoadInputs
setElementOverflow
element report itself as overflowing (or not) on axis. jsdom runs no
layout, so scroll* and client* are both 0 and every overflow test reads as
“fits”; this shadows the prototype getters with own, configurable values so a
test can drive either state. Call it again with the opposite flag to flip the
element back.
Parameters
setPluginHostState
Related: PluginLoaderState
subscribePluginHost
useSyncExternalStore requires so a subscriber detaches on unmount.
Parameters
usePluginContributions
contributions is only
meaningful once status === 'ready' (before then the pass has committed
nothing, so callers render their non-plugin content).
Related: PluginContributionsSnapshot
