@xngui/testing
v0.0.5
Published
Vitest harnesses and TestBed helpers for @xngui component specs
Downloads
606
Readme
@xngui/testing
Shared Vitest helpers and XHarnessBase for component specs. Per-component harnesses live next to the component (input.harness.ts), not in this package.
Install
Used as a dev dependency in the monorepo — not required in consumer apps.
import { configureXComponent, createXComponentHarness, XHarnessBase } from '@xngui/testing';Layout
libs/components/<category>/<name>/src/lib/
<name>.ts
<name>.harness.ts # extends XHarnessBase
<name>.spec.ts # Vitest + TestBedCategory-level shared harness bases (e.g. libs/components/actions/testing/) are allowed when several siblings share the same DOM surface. Do not add per-component or category-specific harnesses to this package.
Package layout
| Location | Purpose |
| ------------------------------------- | ------------------------------------------------------------------------------------------- |
| @xngui/testing | XHarnessBase, factories, asFileList, installXTestEnvironment — category-agnostic only |
| libs/components/<category>/testing/ | Shared bases for siblings in one category |
| *.harness.ts next to component | One harness per component |
Usage
import { beforeEach, describe, expect, it } from 'vitest';
import { configureXComponent, createXComponentHarness } from '@xngui/testing';
import { XInputHarness } from './input.harness';
import { XInput } from './input';
describe('XInput', () => {
beforeEach(async () => {
await configureXComponent(XInput);
});
it('reflects disabled state', async () => {
const { harness } = await createXComponentHarness(XInput, XInputHarness, { disabled: true });
expect(harness.isDisabled()).toBe(true);
expect(harness.dataState()).toBe('disabled');
});
});For components that need a host wrapper or child selector:
import { configureXComponent, createXHostHarness } from '@xngui/testing';
beforeEach(async () => {
await configureXComponent(HostComponent);
});
const { fixture, harness } = await createXHostHarness(HostComponent, XChildHarness, {
selector: 'x-child',
configure: (host) => {
host.value = 'test';
},
});configureXComponent wires provideX() and compiles the TestBed. Prefer createXComponentHarness over hand-rolled fixture setup.
Exports
| Symbol | Purpose |
| ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| XHarnessBase | hostFrom, hostFromSelector, fromElement, element(), query(), queryAll(), attr(), attrOn(), aria(), ariaOn(), data(), dataOn(), hasClass(), hasAttr(), dataIs(), overlayPane(), queryInOverlayOrHost() |
| configureXComponent | TestBed setup with provideX() |
| createXComponentHarness | createComponent + setInput + Harness.hostFrom |
| createXHostHarness | Host wrapper fixture + Harness.hostFromSelector |
| createXComponentFixture | Setup + createComponent only (no harness) |
| asFileList | jsdom FileList for file-input harness actions |
| installXTestEnvironment | matchMedia + CSS.escape polyfills — call from test-setup.ts |
| XConfigureComponentOptions | Extra imports / providers |
| XHarnessClass | Harness constructor type for factories |
Conventions
See .cursor/rules/general/component-testing.mdc — every public input, output, and non-trivial logic must have a focused it block. Query DOM only through the co-located harness.
Reference implementation: libs/components/actions/ (actions/testing/README.md).
Run tests
pnpm nx run components:test
pnpm nx affected -t test