import * as i0 from '@angular/core';
import { InputSignalWithTransform, Signal, Type, Provider, EnvironmentProviders, ModuleWithProviders, EventEmitter, Binding, DebugElement } from '@angular/core';
import { TestBed, DeferBlockState, DeferBlockBehavior, ComponentFixture } from '@angular/core/testing';
import { Routes } from '@angular/router';
import * as _testing_library_dom from '@testing-library/dom';
import { Queries, queries, Config as Config$1, BoundFunctions, PrettyDOMOptions, waitForOptions } 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> = BoundFunctions<Q>;
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: HTMLElement;
    /**
     * @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.
     *
     * @deprecated use the `importOverrides` option instead.
     * @default
     * undefined
     *
     * @example
     * await render(AppComponent, {
     *   componentImports: [
     *     MockChildComponent
     *   ]
     * })
     */
    componentImports?: (Type<unknown> | unknown[])[];
    /**
     * @description
     * Replace specific imports on a standalone component without replacing the entire imports array.
     * Unlike `componentImports`, which replaces all imports, this option lets you swap out targeted
     * child components without needing to enumerate all other imports.
     * Mutually exclusive with `componentImports`.
     *
     * @default
     * undefined
     *
     * @example
     * await render(AppComponent, {
     *   importOverrides: [
     *     { replace: RealChildComponent, with: MockChildComponent }
     *   ]
     * })
     */
    importOverrides?: ImportOverride[];
    /**
     * @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 ImportOverride {
    /** The import to replace (matched by identity) */
    replace: Type<unknown>;
    /** The replacement import to use instead */
    with: Type<unknown> | unknown[];
}
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, ImportOverride, OutputRefKeysWithCallback, RenderComponentOptions, RenderResult, RenderResultQueries, RenderTemplateOptions };
