@testing-library/angular
Version:
Test your Angular components with the dom-testing-library
517 lines (512 loc) • 17.2 kB
TypeScript
import * as i0 from '@angular/core';
import { EventEmitter, DebugElement, Type, Provider, EnvironmentProviders, ModuleWithProviders, InputSignalWithTransform, Signal, Binding } from '@angular/core';
import { ComponentFixture, TestBed, DeferBlockState, DeferBlockBehavior } from '@angular/core/testing';
import { Routes } from '@angular/router';
import * as _testing_library_dom from '@testing-library/dom';
import { Queries, queries, BoundFunction, PrettyDOMOptions, Config as Config$1, waitForOptions, BoundFunctions } from '@testing-library/dom';
export { buildQueries, createEvent, findAllByAltText, findAllByDisplayValue, findAllByLabelText, findAllByPlaceholderText, findAllByRole, findAllByTestId, findAllByText, findAllByTitle, findByAltText, findByDisplayValue, findByLabelText, findByPlaceholderText, findByRole, findByTestId, findByText, findByTitle, fireEvent, getAllByAltText, getAllByDisplayValue, getAllByLabelText, getAllByPlaceholderText, getAllByRole, getAllByTestId, getAllByText, getAllByTitle, getByAltText, getByDisplayValue, getByLabelText, getByPlaceholderText, getByRole, getByTestId, getByText, getByTitle, getDefaultNormalizer, getElementError, getNodeText, getQueriesForElement, getRoles, isInaccessible, logDOM, logRoles, prettyDOM, queries, queryAllByAltText, queryAllByAttribute, queryAllByDisplayValue, queryAllByLabelText, queryAllByPlaceholderText, queryAllByRole, queryAllByTestId, queryAllByText, queryAllByTitle, queryByAltText, queryByAttribute, queryByDisplayValue, queryByLabelText, queryByPlaceholderText, queryByRole, queryByTestId, queryByText, queryByTitle, queryHelpers } from '@testing-library/dom';
interface OutputRef<T> {
subscribe(callback: (value: T) => void): OutputRefSubscription;
}
interface OutputRefSubscription {
unsubscribe(): void;
}
type OutputRefKeysWithCallback<T> = {
[key in keyof T]?: T[key] extends EventEmitter<infer U> ? (val: U) => void : T[key] extends OutputRef<infer U> ? (val: U) => void : never;
};
type RenderResultQueries<Q extends Queries = typeof queries> = {
[P in keyof Q]: BoundFunction<Q[P]>;
};
interface RenderResult<ComponentType, WrapperType = ComponentType> extends RenderResultQueries {
/**
* @description
* The containing DOM node of your rendered Angular Component.
* This is a regular DOM node, so you can call container.querySelector etc. to inspect the children.
*/
container: Element;
/**
* @description
* Prints out the component's DOM with syntax highlighting.
* Accepts an optional parameter, to print out a specific DOM node.
*
* @param
* element: The to be printed HTML element, if not provided it will log the whole component's DOM
*/
debug: (element?: Element | Document | (Element | Document)[], maxLength?: number, options?: PrettyDOMOptions) => void;
/**
* @description
* Trigger a change detection cycle for the component.
*
* For more info see https://angular.io/api/core/testing/ComponentFixture#detectChanges
*/
detectChanges: () => void;
/**
* @description
* The Angular `DebugElement` of the component.
*
* For more info see https://angular.io/api/core/DebugElement
*/
debugElement: DebugElement;
/**
* @description
* The Angular `ComponentFixture` of the component or the wrapper.
* If a template is provided, it will be the fixture of the wrapper.
*
* For more info see https://angular.io/api/core/testing/ComponentFixture
*/
fixture: ComponentFixture<WrapperType>;
/**
* @description
* Navigates to the href of the element or to the path.
*
*/
navigate: (elementOrPath: Element | string, basePath?: string) => Promise<boolean>;
/**
* @description
* Re-render the same component with different properties.
* Properties not passed in again are removed.
*/
rerender: (properties?: Pick<RenderTemplateOptions<ComponentType>, 'componentProperties' | 'componentInputs' | 'inputs' | 'componentOutputs' | 'on' | 'detectChangesOnRender'> & {
partialUpdate?: boolean;
}) => Promise<void>;
/**
* @description
* Set the state of a deferrable block.
*/
renderDeferBlock: (deferBlockState: DeferBlockState, deferBlockIndex?: number) => Promise<void>;
}
declare const ALIASED_INPUT_BRAND: unique symbol;
type AliasedInput<T> = T & {
[ALIASED_INPUT_BRAND]: T;
};
type AliasedInputs = Record<string, AliasedInput<unknown>>;
type ComponentInput<T> = {
[P in keyof T]?: T[P] extends InputSignalWithTransform<any, infer U> ? U : T[P] extends Signal<infer U> ? U : T[P];
} | AliasedInputs;
/**
* @description
* Creates an aliased input branded type with a value
*
*/
declare function aliasedInput<TAlias extends string, T>(alias: TAlias, value: T): Record<TAlias, AliasedInput<T>>;
interface RenderComponentOptions<ComponentType, Q extends Queries = typeof queries> {
/**
* @description
* Automatically detect changes as a "real" running component would do.
*
* @default
* true
*
* @example
* await render(AppComponent, {
* autoDetectChanges: false
* })
*/
autoDetectChanges?: boolean;
/**
* @description
* Invokes `detectChanges` after the component is rendered
*
* @default
* true
*
* @example
* await render(AppComponent, {
* detectChangesOnRender: false
* })
*/
detectChangesOnRender?: boolean;
/**
* @description
* A collection of components, directives and pipes needed to render the component, for example, nested components of the component.
*
* For more info see https://angular.io/api/core/NgModule#declarations
*
* @default
* []
*
* @example
* await render(AppComponent, {
* declarations: [ CustomerDetailComponent, ButtonComponent ]
* })
*/
declarations?: (Type<unknown> | unknown[])[];
/**
* @description
* A collection of providers needed to render the component via Dependency Injection, for example, injectable services or tokens.
*
* For more info see https://angular.io/api/core/NgModule#providers
*
* @default
* []
*
* @example
* await render(AppComponent, {
* providers: [
* CustomersService,
* {
* provide: MAX_CUSTOMERS_TOKEN,
* useValue: 10
* }
* ]
* })
*/
providers?: (Provider | EnvironmentProviders)[];
/**
* @description
* A collection of imports needed to render the component, for example, shared modules.
*
* For more info see https://angular.io/api/core/NgModule#imports
*
* @default
* `[]`
*
* @example
* await render(AppComponent, {
* imports: [
* AppSharedModule,
* MaterialModule,
* ]
* })
*/
imports?: (Type<unknown> | ModuleWithProviders<unknown>)[];
/**
* @description
* A collection of schemas needed to render the component.
* Allowed values are `NO_ERRORS_SCHEMA` and `CUSTOM_ELEMENTS_SCHEMA`.
*
* For more info see https://angular.io/api/core/NgModule#schemas
*
* @default
* []
*
* @example
* await render(AppComponent, {
* schemas: [
* NO_ERRORS_SCHEMA,
* ]
* })
*/
schemas?: any[];
/**
* @description
* An object to set properties of the component
*
* @default
* {}
*
* @example
* await render(AppComponent, {
* componentProperties: {
* counterValue: 10,
* send: (value) => { ... }
* }
* })
*/
componentProperties?: Partial<ComponentType>;
/**
* @description
* An object to set `@Input` properties of the component
*
* @deprecated use the `inputs` option instead. When you need to use aliases, use the `aliasedInput(...)` helper function.
* @default
* {}
*
* @example
* await render(AppComponent, {
* componentInputs: {
* counterValue: 10
* }
* })
*/
componentInputs?: Partial<ComponentType> | Record<string, unknown>;
/**
* @description
* An object to set `@Input` or `input()` properties of the component
*
* @default
* {}
*
* @example
* await render(AppComponent, {
* inputs: {
* counterValue: 10,
* // explicitly define aliases using aliasedInput
* ...aliasedInput('someAlias', 'someValue')
* }
* })
*/
inputs?: ComponentInput<ComponentType>;
/**
* @description
* An object to set `@Output` properties of the component
* @deprecated use the `on` option instead. When it is necessary to override properties, use the `componentProperties` option.
* @default
* {}
*
* @example
* const sendValue = new EventEmitter<any>();
* await render(AppComponent, {
* componentOutputs: {
* send: {
* emit: sendValue
* }
* }
* })
*/
componentOutputs?: Partial<ComponentType>;
/**
* @description
* An object with callbacks to subscribe to EventEmitters/Observables of the component
*
* @default
* {}
*
* @example
* const sendValue = (value) => { ... }
* await render(AppComponent, {
* on: {
* send: (value) => sendValue(value)
* }
* })
*/
on?: OutputRefKeysWithCallback<ComponentType>;
/**
* @description
* An array of bindings to apply to the component using Angular's native bindings API.
* This provides a more direct way to bind inputs and outputs compared to the `inputs` and `on` options.
*
* @default
* []
*
* @example
* import { inputBinding, outputBinding, twoWayBinding } from '@angular/core';
* import { signal } from '@angular/core';
*
* await render(AppComponent, {
* bindings: [
* inputBinding('value', () => 'test value'),
* outputBinding('click', (event) => console.log(event)),
* twoWayBinding('name', signal('initial value'))
* ]
* })
*/
bindings?: Binding[];
/**
* @description
* A collection of providers to inject dependencies of the component.
*
* For more info see https://angular.io/api/core/Directive#providers
*
* @default
* []
*
* @example
* await render(AppComponent, {
* componentProviders: [
* AppComponentService
* ]
* })
*/
componentProviders?: Provider[];
/**
* @description
* Collection of child component specified providers to override with
*
* @default
* []
*
* @example
* await render(AppComponent, {
* childComponentOverrides: [
* {
* component: ChildOfAppComponent,
* providers: [{ provide: MyService, useValue: { hello: 'world' } }]
* }
* ]
* })
*
*/
childComponentOverrides?: ComponentOverride<any>[];
/**
* @description
* A collection of imports to override a standalone component's imports with.
*
* @default
* undefined
*
* @example
* await render(AppComponent, {
* componentImports: [
* MockChildComponent
* ]
* })
*/
componentImports?: (Type<unknown> | unknown[])[];
/**
* @description
* Queries to bind. Overrides the default set from DOM Testing Library unless merged.
*
* @default
* undefined
*
* @example
* import * as customQueries from 'custom-queries'
* import { queries } from '@testing-library/angular'
*
* await render(AppComponent, {
* queries: { ...queries, ...customQueries }
* })
*/
queries?: Q;
/**
* @description
* Exclude the component to be automatically be added as a declaration.
* This is needed when the component is declared in an imported module.
*
* @default
* false
*
* @example
* await render(AppComponent, {
* imports: [AppModule], // a module that includes AppComponent
* excludeComponentDeclaration: true
* })
*/
excludeComponentDeclaration?: boolean;
/**
* @description
* The route configuration to set up the router service via `RouterTestingModule.withRoutes`.
* For more info see https://angular.io/api/router/Routes.
*
* @example
* await render(AppComponent, {
* declarations: [ChildComponent],
* routes: [
* {
* path: '',
* children: [
* {
* path: 'child/:id',
* component: ChildComponent
* }
* ]
* }
* ]
* })
*/
routes?: Routes;
/**
* @description
* Specifies which route should be initially navigated to
*
* @example
* await render(AppComponent, {
* initialRoute: 'myroute',
* routes: [
* { path: '', component: HomeComponent },
* { path: 'myroute', component: SecondaryComponent }
* ]
* })
*/
initialRoute?: string;
/**
* @description
* Removes the Angular attributes (ng-version, and root-id) from the fixture.
*
* @default
* `false`
*
* @example
* await render(AppComponent, {
* removeAngularAttributes: true
* })
*/
removeAngularAttributes?: boolean;
/**
* @description
* Callback to configure the testbed before the compilation.
*
* @default
* () => {}
*
* @example
* await render(AppComponent, {
* configureTestBed: (testBed) => { }
* })
*/
configureTestBed?: (testbed: TestBed) => void;
/**
* @description
* Set the initial state of a deferrable block.
*/
deferBlockStates?: DeferBlockState | {
deferBlockState: DeferBlockState;
deferBlockIndex: number;
}[];
/**
* @description
* Set the defer blocks behavior.
*/
deferBlockBehavior?: DeferBlockBehavior;
}
interface ComponentOverride<T> {
component: Type<T>;
providers: Provider[];
}
interface RenderTemplateOptions<WrapperType, Properties extends object = {}, Q extends Queries = typeof queries> extends RenderComponentOptions<Properties, Q> {
/**
* @description
* An Angular component to wrap the component in.
* The template will be overridden with the `template` option.
* NOTE: A standalone component cannot be used as a wrapper.
*
* @default
* `WrapperComponent`, an empty component that strips the `ng-version` attribute
*
* @example
* await render(`<div spoiler message='SPOILER'></div>`, {
* declarations: [SpoilerDirective]
* wrapper: CustomWrapperComponent
* })
*/
wrapper?: Type<WrapperType>;
componentProperties?: Partial<WrapperType & Properties>;
}
interface Config extends Pick<RenderComponentOptions<any>, 'excludeComponentDeclaration'> {
/**
* DOM Testing Library config
* @link https://testing-library.com/docs/dom-testing-library/api-configuration/
*/
dom: Partial<Config$1>;
/**
* Imports that are added to the imports
*/
defaultImports?: (Type<unknown> | ModuleWithProviders<unknown>)[];
}
declare function configure(newConfig: Partial<Config> | ((config: Partial<Config>) => Partial<Config>)): void;
declare function getConfig(): Config;
declare function render<ComponentType>(component: Type<ComponentType>, renderOptions?: RenderComponentOptions<ComponentType>): Promise<RenderResult<ComponentType, ComponentType>>;
declare function render<WrapperType = WrapperComponent>(template: string, renderOptions?: RenderTemplateOptions<WrapperType>): Promise<RenderResult<WrapperType>>;
declare class WrapperComponent {
static ɵfac: i0.ɵɵFactoryDeclaration<WrapperComponent, never>;
static ɵcmp: i0.ɵɵComponentDeclaration<WrapperComponent, "atl-wrapper-component", never, {}, {}, never, never, false, never>;
}
/**
* Re-export screen with patched queries
*/
declare const screen: _testing_library_dom.Screen<typeof queries>;
/**
* Re-export within with patched queries
*/
declare const within: <QueriesToBind extends Queries = typeof queries, T extends QueriesToBind = QueriesToBind>(element: HTMLElement, queriesToBind?: T) => BoundFunctions<T>;
/**
* Re-export waitFor with patched waitFor
*/
declare function waitFor<T>(callback: () => T extends Promise<any> ? never : T, options?: waitForOptions): Promise<T>;
/**
* Re-export waitForElementToBeRemoved with patched waitForElementToBeRemoved
*/
declare function waitForElementToBeRemoved<T>(callback: (() => T) | T, options?: waitForOptions): Promise<void>;
export { aliasedInput, configure, getConfig, render, screen, waitFor, waitForElementToBeRemoved, within };
export type { AliasedInput, AliasedInputs, ComponentInput, ComponentOverride, Config, OutputRefKeysWithCallback, RenderComponentOptions, RenderResult, RenderResultQueries, RenderTemplateOptions };