UNPKG

@testing-library/angular

Version:
517 lines (512 loc) 17.2 kB
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 };