import { act } from 'preact/test-utils';
import { ARIARole } from 'aria-query';
import { OptionsReceived } from 'pretty-format';
import * as prettyFormat from 'pretty-format';

export { act }

export declare type AllByAttribute = (
attribute: string,
container: HTMLElement,
id: Matcher,
options?: MatcherOptions,
) => HTMLElement[]

export declare type AllByBoundAttribute<T extends HTMLElement = HTMLElement> = (
container: HTMLElement,
id: Matcher,
options?: MatcherOptions,
) => T[]

export declare type AllByRole<T extends HTMLElement = HTMLElement> = (
container: HTMLElement,
role: ByRoleMatcher,
options?: ByRoleOptions,
) => T[]

export declare type AllByText<T extends HTMLElement = HTMLElement> = (
container: HTMLElement,
id: Matcher,
options?: SelectorMatcherOptions,
) => T[]

export declare type BoundFunction<T> = T extends (
container: HTMLElement,
...args: infer P
) => infer R
? (...args: P) => R
: never

export declare type BoundFunctions<Q> = Q extends typeof queries
? {
    getByLabelText<T extends HTMLElement = HTMLElement>(
    ...args: Parameters<BoundFunction<queries.GetByText<T>>>
    ): ReturnType<queries.GetByText<T>>
    getAllByLabelText<T extends HTMLElement = HTMLElement>(
    ...args: Parameters<BoundFunction<queries.AllByText<T>>>
    ): ReturnType<queries.AllByText<T>>
    queryByLabelText<T extends HTMLElement = HTMLElement>(
    ...args: Parameters<BoundFunction<queries.QueryByText<T>>>
    ): ReturnType<queries.QueryByText<T>>
    queryAllByLabelText<T extends HTMLElement = HTMLElement>(
    ...args: Parameters<BoundFunction<queries.AllByText<T>>>
    ): ReturnType<queries.AllByText<T>>
    findByLabelText<T extends HTMLElement = HTMLElement>(
    ...args: Parameters<BoundFunction<queries.FindByText<T>>>
    ): ReturnType<queries.FindByText<T>>
    findAllByLabelText<T extends HTMLElement = HTMLElement>(
    ...args: Parameters<BoundFunction<queries.FindAllByText<T>>>
    ): ReturnType<queries.FindAllByText<T>>
    getByPlaceholderText<T extends HTMLElement = HTMLElement>(
    ...args: Parameters<BoundFunction<queries.GetByBoundAttribute<T>>>
    ): ReturnType<queries.GetByBoundAttribute<T>>
    getAllByPlaceholderText<T extends HTMLElement = HTMLElement>(
    ...args: Parameters<BoundFunction<queries.AllByBoundAttribute<T>>>
    ): ReturnType<queries.AllByBoundAttribute<T>>
    queryByPlaceholderText<T extends HTMLElement = HTMLElement>(
    ...args: Parameters<BoundFunction<queries.QueryByBoundAttribute<T>>>
    ): ReturnType<queries.QueryByBoundAttribute<T>>
    queryAllByPlaceholderText<T extends HTMLElement = HTMLElement>(
    ...args: Parameters<BoundFunction<queries.AllByBoundAttribute<T>>>
    ): ReturnType<queries.AllByBoundAttribute<T>>
    findByPlaceholderText<T extends HTMLElement = HTMLElement>(
    ...args: Parameters<BoundFunction<queries.FindByBoundAttribute<T>>>
    ): ReturnType<queries.FindByBoundAttribute<T>>
    findAllByPlaceholderText<T extends HTMLElement = HTMLElement>(
    ...args: Parameters<BoundFunction<queries.FindAllByBoundAttribute<T>>>
    ): ReturnType<queries.FindAllByBoundAttribute<T>>
    getByText<T extends HTMLElement = HTMLElement>(
    ...args: Parameters<BoundFunction<queries.GetByText<T>>>
    ): ReturnType<queries.GetByText<T>>
    getAllByText<T extends HTMLElement = HTMLElement>(
    ...args: Parameters<BoundFunction<queries.AllByText<T>>>
    ): ReturnType<queries.AllByText<T>>
    queryByText<T extends HTMLElement = HTMLElement>(
    ...args: Parameters<BoundFunction<queries.QueryByText<T>>>
    ): ReturnType<queries.QueryByText<T>>
    queryAllByText<T extends HTMLElement = HTMLElement>(
    ...args: Parameters<BoundFunction<queries.AllByText<T>>>
    ): ReturnType<queries.AllByText<T>>
    findByText<T extends HTMLElement = HTMLElement>(
    ...args: Parameters<BoundFunction<queries.FindByText<T>>>
    ): ReturnType<queries.FindByText<T>>
    findAllByText<T extends HTMLElement = HTMLElement>(
    ...args: Parameters<BoundFunction<queries.FindAllByText<T>>>
    ): ReturnType<queries.FindAllByText<T>>
    getByAltText<T extends HTMLElement = HTMLElement>(
    ...args: Parameters<BoundFunction<queries.GetByBoundAttribute<T>>>
    ): ReturnType<queries.GetByBoundAttribute<T>>
    getAllByAltText<T extends HTMLElement = HTMLElement>(
    ...args: Parameters<BoundFunction<queries.AllByBoundAttribute<T>>>
    ): ReturnType<queries.AllByBoundAttribute<T>>
    queryByAltText<T extends HTMLElement = HTMLElement>(
    ...args: Parameters<BoundFunction<queries.QueryByBoundAttribute<T>>>
    ): ReturnType<queries.QueryByBoundAttribute<T>>
    queryAllByAltText<T extends HTMLElement = HTMLElement>(
    ...args: Parameters<BoundFunction<queries.AllByBoundAttribute<T>>>
    ): ReturnType<queries.AllByBoundAttribute<T>>
    findByAltText<T extends HTMLElement = HTMLElement>(
    ...args: Parameters<BoundFunction<queries.FindByBoundAttribute<T>>>
    ): ReturnType<queries.FindByBoundAttribute<T>>
    findAllByAltText<T extends HTMLElement = HTMLElement>(
    ...args: Parameters<BoundFunction<queries.FindAllByBoundAttribute<T>>>
    ): ReturnType<queries.FindAllByBoundAttribute<T>>
    getByTitle<T extends HTMLElement = HTMLElement>(
    ...args: Parameters<BoundFunction<queries.GetByBoundAttribute<T>>>
    ): ReturnType<queries.GetByBoundAttribute<T>>
    getAllByTitle<T extends HTMLElement = HTMLElement>(
    ...args: Parameters<BoundFunction<queries.AllByBoundAttribute<T>>>
    ): ReturnType<queries.AllByBoundAttribute<T>>
    queryByTitle<T extends HTMLElement = HTMLElement>(
    ...args: Parameters<BoundFunction<queries.QueryByBoundAttribute<T>>>
    ): ReturnType<queries.QueryByBoundAttribute<T>>
    queryAllByTitle<T extends HTMLElement = HTMLElement>(
    ...args: Parameters<BoundFunction<queries.AllByBoundAttribute<T>>>
    ): ReturnType<queries.AllByBoundAttribute<T>>
    findByTitle<T extends HTMLElement = HTMLElement>(
    ...args: Parameters<BoundFunction<queries.FindByBoundAttribute<T>>>
    ): ReturnType<queries.FindByBoundAttribute<T>>
    findAllByTitle<T extends HTMLElement = HTMLElement>(
    ...args: Parameters<BoundFunction<queries.FindAllByBoundAttribute<T>>>
    ): ReturnType<queries.FindAllByBoundAttribute<T>>
    getByDisplayValue<T extends HTMLElement = HTMLElement>(
    ...args: Parameters<BoundFunction<queries.GetByBoundAttribute<T>>>
    ): ReturnType<queries.GetByBoundAttribute<T>>
    getAllByDisplayValue<T extends HTMLElement = HTMLElement>(
    ...args: Parameters<BoundFunction<queries.AllByBoundAttribute<T>>>
    ): ReturnType<queries.AllByBoundAttribute<T>>
    queryByDisplayValue<T extends HTMLElement = HTMLElement>(
    ...args: Parameters<BoundFunction<queries.QueryByBoundAttribute<T>>>
    ): ReturnType<queries.QueryByBoundAttribute<T>>
    queryAllByDisplayValue<T extends HTMLElement = HTMLElement>(
    ...args: Parameters<BoundFunction<queries.AllByBoundAttribute<T>>>
    ): ReturnType<queries.AllByBoundAttribute<T>>
    findByDisplayValue<T extends HTMLElement = HTMLElement>(
    ...args: Parameters<BoundFunction<queries.FindByBoundAttribute<T>>>
    ): ReturnType<queries.FindByBoundAttribute<T>>
    findAllByDisplayValue<T extends HTMLElement = HTMLElement>(
    ...args: Parameters<BoundFunction<queries.FindAllByBoundAttribute<T>>>
    ): ReturnType<queries.FindAllByBoundAttribute<T>>
    getByRole<T extends HTMLElement = HTMLElement>(
    ...args: Parameters<BoundFunction<queries.GetByRole<T>>>
    ): ReturnType<queries.GetByRole<T>>
    getAllByRole<T extends HTMLElement = HTMLElement>(
    ...args: Parameters<BoundFunction<queries.AllByRole<T>>>
    ): ReturnType<queries.AllByRole<T>>
    queryByRole<T extends HTMLElement = HTMLElement>(
    ...args: Parameters<BoundFunction<queries.QueryByRole<T>>>
    ): ReturnType<queries.QueryByRole<T>>
    queryAllByRole<T extends HTMLElement = HTMLElement>(
    ...args: Parameters<BoundFunction<queries.AllByRole<T>>>
    ): ReturnType<queries.AllByRole<T>>
    findByRole<T extends HTMLElement = HTMLElement>(
    ...args: Parameters<BoundFunction<queries.FindByRole<T>>>
    ): ReturnType<queries.FindByRole<T>>
    findAllByRole<T extends HTMLElement = HTMLElement>(
    ...args: Parameters<BoundFunction<queries.FindAllByRole<T>>>
    ): ReturnType<queries.FindAllByRole<T>>
    getByTestId<T extends HTMLElement = HTMLElement>(
    ...args: Parameters<BoundFunction<queries.GetByBoundAttribute<T>>>
    ): ReturnType<queries.GetByBoundAttribute<T>>
    getAllByTestId<T extends HTMLElement = HTMLElement>(
    ...args: Parameters<BoundFunction<queries.AllByBoundAttribute<T>>>
    ): ReturnType<queries.AllByBoundAttribute<T>>
    queryByTestId<T extends HTMLElement = HTMLElement>(
    ...args: Parameters<BoundFunction<queries.QueryByBoundAttribute<T>>>
    ): ReturnType<queries.QueryByBoundAttribute<T>>
    queryAllByTestId<T extends HTMLElement = HTMLElement>(
    ...args: Parameters<BoundFunction<queries.AllByBoundAttribute<T>>>
    ): ReturnType<queries.AllByBoundAttribute<T>>
    findByTestId<T extends HTMLElement = HTMLElement>(
    ...args: Parameters<BoundFunction<queries.FindByBoundAttribute<T>>>
    ): ReturnType<queries.FindByBoundAttribute<T>>
    findAllByTestId<T extends HTMLElement = HTMLElement>(
    ...args: Parameters<BoundFunction<queries.FindAllByBoundAttribute<T>>>
    ): ReturnType<queries.FindAllByBoundAttribute<T>>
} & {
    [P in keyof Q]: BoundFunction<Q[P]>
}
: {
    [P in keyof Q]: BoundFunction<Q[P]>
}

export declare function buildQueries<Arguments extends any[]>(
queryAllBy: GetAllBy<Arguments>,
getMultipleError: GetErrorFunction<Arguments>,
getMissingError: GetErrorFunction<Arguments>,
): BuiltQueryMethods<Arguments>

export declare type BuiltQueryMethods<Arguments extends any[]> = [
QueryBy<Arguments>,
GetAllBy<Arguments>,
GetBy<Arguments>,
FindAllBy<Arguments>,
FindBy<Arguments>,
]

export declare type ByRoleMatcher = ARIARole | (string & {})

export declare interface ByRoleOptions {
    /** suppress suggestions for a specific query */
    suggest?: boolean
    /**
     * If true includes elements in the query set that are usually excluded from
     * the accessibility tree. `role="none"` or `role="presentation"` are included
     * in either case.
     */
    hidden?: boolean
    /**
     * If true only includes elements in the query set that are marked as
     * selected in the accessibility tree, i.e., `aria-selected="true"`
     */
    selected?: boolean
    /**
     * If true only includes elements in the query set that are marked as
     * busy in the accessibility tree, i.e., `aria-busy="true"`
     */
    busy?: boolean
    /**
     * If true only includes elements in the query set that are marked as
     * checked in the accessibility tree, i.e., `aria-checked="true"`
     */
    checked?: boolean
    /**
     * If true only includes elements in the query set that are marked as
     * pressed in the accessibility tree, i.e., `aria-pressed="true"`
     */
    pressed?: boolean
    /**
     * Filters elements by their `aria-current` state. `true` and `false` match `aria-current="true"` and `aria-current="false"` (as well as a missing `aria-current` attribute) respectively.
     */
    current?: boolean | string
    /**
     * If true only includes elements in the query set that are marked as
     * expanded in the accessibility tree, i.e., `aria-expanded="true"`
     */
    expanded?: boolean
    /**
     * Includes elements with the `"heading"` role matching the indicated level,
     * either by the semantic HTML heading elements `<h1>-<h6>` or matching
     * the `aria-level` attribute.
     */
    level?: number
    value?: {
        now?: number
        min?: number
        max?: number
        text?: Matcher
    }
    /**
     * Includes every role used in the `role` attribute
     * For example *ByRole('progressbar', {queryFallbacks: true})` will find <div role="meter progressbar">`.
     */
    queryFallbacks?: boolean
    /**
     * Only considers elements with the specified accessible name.
     */
    name?:
    | RegExp
    | string
    | ((accessibleName: string, element: Element) => boolean)
    /**
     * Only considers elements with the specified accessible description.
     */
    description?:
    | RegExp
    | string
    | ((accessibleDescription: string, element: Element) => boolean)
}

/**
 * Cleanup elements rendered to the page and Preact trees that were mounted with render.
 *
 * @public
 */
export declare function cleanup(): void;

export declare function computeHeadingLevel(element: Element): number | undefined

export declare interface Config {
    testIdAttribute: string
    /**
     * WARNING: `unstable` prefix means this API may change in patch and minor releases.
     * @param cb
     */
    unstable_advanceTimersWrapper(cb: (...args: unknown[]) => unknown): unknown
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    asyncWrapper(cb: (...args: any[]) => any): Promise<any>
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    eventWrapper(cb: (...args: any[]) => any): void
    asyncUtilTimeout: number
    computedStyleSupportsPseudoElements: boolean
    defaultHidden: boolean
    /** default value for the `ignore` option in `ByText` queries */
    defaultIgnore: string
    showOriginalStackTrace: boolean
    throwSuggestions: boolean
    getElementError: (message: string | null, container: Element) => Error
}

export declare interface ConfigFn {
    (existingConfig: Config): Partial<Config>
}

export declare function configure(configDelta: ConfigFn | Partial<Config>): void

export declare const createEvent: CreateObject & CreateFunction;

export declare type CreateFunction = (
eventName: string,
node: Document | Element | Window | Node,
init?: {},
options?: {EventType?: string; defaultInit?: {}},
) => Event

export declare type CreateObject = {
    [K in EventType_2]: (
    element: Document | Element | Window | Node,
    options?: {},
    ) => Event
}

export declare interface DefaultNormalizerOptions {
    trim?: boolean
    collapseWhitespace?: boolean
}

/**
 * @public
 * The lynx element tree
 */
export declare type ElementTree = ReturnType<typeof initElementTree>;

/**
 * The Element PAPI Types
 * @public
 */
declare type ElementTreeGlobals = PickUnderscoreKeys<ElementTree>;

export declare type EventType =
| 'focus'
| 'blur'
| 'scroll'
| 'wheel'
| 'tap'
| 'longtap'
| 'bgload'
| 'bgerror'
| 'touchstart'
| 'touchmove'
| 'touchcancel'
| 'touchend'
| 'longpress'
| 'transitionstart'
| 'transitioncancel'
| 'transitionend'
| 'animationstart'
| 'animationiteration'
| 'animationcancel'
| 'animationend'
| 'mousedown'
| 'mouseup'
| 'mousemove'
| 'mouseclick'
| 'mousedblclick'
| 'mouselongpress'
| 'keydown'
| 'keyup'
| 'layoutchange'
| 'scrolltoupper'
| 'scrolltolower'
| 'scrollend'
| 'contentsizechanged'
| 'scrolltoupperedge'
| 'scrolltoloweredge'
| 'scrolltonormalstate';

declare type EventType_2 =
| 'copy'
| 'cut'
| 'paste'
| 'compositionEnd'
| 'compositionStart'
| 'compositionUpdate'
| 'keyDown'
| 'keyPress'
| 'keyUp'
| 'focus'
| 'blur'
| 'focusIn'
| 'focusOut'
| 'change'
| 'input'
| 'invalid'
| 'submit'
| 'reset'
| 'click'
| 'contextMenu'
| 'dblClick'
| 'drag'
| 'dragEnd'
| 'dragEnter'
| 'dragExit'
| 'dragLeave'
| 'dragOver'
| 'dragStart'
| 'drop'
| 'mouseDown'
| 'mouseEnter'
| 'mouseLeave'
| 'mouseMove'
| 'mouseOut'
| 'mouseOver'
| 'mouseUp'
| 'popState'
| 'select'
| 'touchCancel'
| 'touchEnd'
| 'touchMove'
| 'touchStart'
| 'resize'
| 'scroll'
| 'wheel'
| 'abort'
| 'canPlay'
| 'canPlayThrough'
| 'durationChange'
| 'emptied'
| 'encrypted'
| 'ended'
| 'loadedData'
| 'loadedMetadata'
| 'loadStart'
| 'pause'
| 'play'
| 'playing'
| 'progress'
| 'rateChange'
| 'seeked'
| 'seeking'
| 'stalled'
| 'suspend'
| 'timeUpdate'
| 'volumeChange'
| 'waiting'
| 'load'
| 'error'
| 'animationStart'
| 'animationEnd'
| 'animationIteration'
| 'transitionCancel'
| 'transitionEnd'
| 'transitionRun'
| 'transitionStart'
| 'doubleClick'
| 'pointerOver'
| 'pointerEnter'
| 'pointerDown'
| 'pointerMove'
| 'pointerUp'
| 'pointerCancel'
| 'pointerOut'
| 'pointerLeave'
| 'gotPointerCapture'
| 'lostPointerCapture'
| 'offline'
| 'online'
| 'pageHide'
| 'pageShow'

/**
 * @public
 */
declare type FilterUnderscoreKeys<T> = {
    [K in keyof T]: K extends `__${string}` ? K : never;
}[keyof T];

export declare type FindAllBy<Arguments extends any[]> = QueryMethod<
[Arguments[0], Arguments[1]?, waitForOptions?],
Promise<HTMLElement[]>
>

export declare function findAllByAltText<T extends HTMLElement = HTMLElement>(
...args: Parameters<FindAllByBoundAttribute<T>>
): ReturnType<FindAllByBoundAttribute<T>>

export declare type FindAllByBoundAttribute<T extends HTMLElement = HTMLElement> = (
container: HTMLElement,
id: Matcher,
options?: MatcherOptions,
waitForElementOptions?: waitForOptions,
) => Promise<T[]>

export declare function findAllByDisplayValue<T extends HTMLElement = HTMLElement>(
...args: Parameters<FindAllByBoundAttribute<T>>
): ReturnType<FindAllByBoundAttribute<T>>

export declare function findAllByLabelText<T extends HTMLElement = HTMLElement>(
...args: Parameters<FindAllByText<T>>
): ReturnType<FindAllByText<T>>

export declare function findAllByPlaceholderText<T extends HTMLElement = HTMLElement>(
...args: Parameters<FindAllByBoundAttribute<T>>
): ReturnType<FindAllByBoundAttribute<T>>

export declare type FindAllByRole<T extends HTMLElement = HTMLElement> = (
container: HTMLElement,
role: ByRoleMatcher,
options?: ByRoleOptions,
waitForElementOptions?: waitForOptions,
) => Promise<T[]>

export declare function findAllByRole<T extends HTMLElement = HTMLElement>(
...args: Parameters<FindAllByRole<T>>
): ReturnType<FindAllByRole<T>>

export declare function findAllByTestId<T extends HTMLElement = HTMLElement>(
...args: Parameters<FindAllByBoundAttribute<T>>
): ReturnType<FindAllByBoundAttribute<T>>

export declare type FindAllByText<T extends HTMLElement = HTMLElement> = (
container: HTMLElement,
id: Matcher,
options?: SelectorMatcherOptions,
waitForElementOptions?: waitForOptions,
) => Promise<T[]>

export declare function findAllByText<T extends HTMLElement = HTMLElement>(
...args: Parameters<FindAllByText<T>>
): ReturnType<FindAllByText<T>>

export declare function findAllByTitle<T extends HTMLElement = HTMLElement>(
...args: Parameters<FindAllByBoundAttribute<T>>
): ReturnType<FindAllByBoundAttribute<T>>

export declare type FindBy<Arguments extends any[]> = QueryMethod<
[Arguments[0], Arguments[1]?, waitForOptions?],
Promise<HTMLElement>
>

export declare function findByAltText<T extends HTMLElement = HTMLElement>(
...args: Parameters<FindByBoundAttribute<T>>
): ReturnType<FindByBoundAttribute<T>>

export declare type FindByBoundAttribute<T extends HTMLElement = HTMLElement> = (
container: HTMLElement,
id: Matcher,
options?: MatcherOptions,
waitForElementOptions?: waitForOptions,
) => Promise<T>

export declare function findByDisplayValue<T extends HTMLElement = HTMLElement>(
...args: Parameters<FindByBoundAttribute<T>>
): ReturnType<FindByBoundAttribute<T>>

export declare function findByLabelText<T extends HTMLElement = HTMLElement>(
...args: Parameters<FindByText<T>>
): ReturnType<FindByText<T>>

export declare function findByPlaceholderText<T extends HTMLElement = HTMLElement>(
...args: Parameters<FindByBoundAttribute<T>>
): ReturnType<FindByBoundAttribute<T>>

export declare type FindByRole<T extends HTMLElement = HTMLElement> = (
container: HTMLElement,
role: ByRoleMatcher,
options?: ByRoleOptions,
waitForElementOptions?: waitForOptions,
) => Promise<T>

export declare function findByRole<T extends HTMLElement = HTMLElement>(
...args: Parameters<FindByRole<T>>
): ReturnType<FindByRole<T>>

export declare function findByTestId<T extends HTMLElement = HTMLElement>(
...args: Parameters<FindByBoundAttribute<T>>
): ReturnType<FindByBoundAttribute<T>>

export declare type FindByText<T extends HTMLElement = HTMLElement> = (
container: HTMLElement,
id: Matcher,
options?: SelectorMatcherOptions,
waitForElementOptions?: waitForOptions,
) => Promise<T>

export declare function findByText<T extends HTMLElement = HTMLElement>(
...args: Parameters<FindByText<T>>
): ReturnType<FindByText<T>>

export declare function findByTitle<T extends HTMLElement = HTMLElement>(
...args: Parameters<FindByBoundAttribute<T>>
): ReturnType<FindByBoundAttribute<T>>

export declare const fireEvent: FireFunction & FireObject;

export declare type FireFunction = (
element: Document | Element | Window | Node,
event: Event,
) => boolean

export declare type FireObject = {
    [K in EventType]: FireObject_2[EventType_2];
};

declare type FireObject_2 = {
    [K in EventType_2]: (
    element: Document | Element | Window | Node,
    options?: {},
    ) => boolean
}

export declare type GetAllBy<Arguments extends any[]> = QueryMethod<
Arguments,
HTMLElement[]
>

export declare function getAllByAltText<T extends HTMLElement = HTMLElement>(
...args: Parameters<AllByBoundAttribute<T>>
): ReturnType<AllByBoundAttribute<T>>

export declare function getAllByDisplayValue<T extends HTMLElement = HTMLElement>(
...args: Parameters<AllByBoundAttribute<T>>
): ReturnType<AllByBoundAttribute<T>>

export declare function getAllByLabelText<T extends HTMLElement = HTMLElement>(
...args: Parameters<AllByText<T>>
): ReturnType<AllByText<T>>

export declare function getAllByPlaceholderText<T extends HTMLElement = HTMLElement>(
...args: Parameters<AllByBoundAttribute<T>>
): ReturnType<AllByBoundAttribute<T>>

export declare function getAllByRole<T extends HTMLElement = HTMLElement>(
...args: Parameters<AllByRole<T>>
): ReturnType<AllByRole<T>>

export declare function getAllByTestId<T extends HTMLElement = HTMLElement>(
...args: Parameters<AllByBoundAttribute<T>>
): ReturnType<AllByBoundAttribute<T>>

export declare function getAllByText<T extends HTMLElement = HTMLElement>(
...args: Parameters<AllByText<T>>
): ReturnType<AllByText<T>>

export declare function getAllByTitle<T extends HTMLElement = HTMLElement>(
...args: Parameters<AllByBoundAttribute<T>>
): ReturnType<AllByBoundAttribute<T>>

export declare type GetBy<Arguments extends any[]> = QueryMethod<Arguments, HTMLElement>

export declare function getByAltText<T extends HTMLElement = HTMLElement>(
...args: Parameters<GetByBoundAttribute<T>>
): ReturnType<GetByBoundAttribute<T>>

export declare type GetByBoundAttribute<T extends HTMLElement = HTMLElement> = (
container: HTMLElement,
id: Matcher,
options?: MatcherOptions,
) => T

export declare function getByDisplayValue<T extends HTMLElement = HTMLElement>(
...args: Parameters<GetByBoundAttribute<T>>
): ReturnType<GetByBoundAttribute<T>>

export declare function getByLabelText<T extends HTMLElement = HTMLElement>(
...args: Parameters<GetByText<T>>
): ReturnType<GetByText<T>>

export declare function getByPlaceholderText<T extends HTMLElement = HTMLElement>(
...args: Parameters<GetByBoundAttribute<T>>
): ReturnType<GetByBoundAttribute<T>>

export declare type GetByRole<T extends HTMLElement = HTMLElement> = (
container: HTMLElement,
role: ByRoleMatcher,
options?: ByRoleOptions,
) => T

export declare function getByRole<T extends HTMLElement = HTMLElement>(
...args: Parameters<GetByRole<T>>
): ReturnType<GetByRole<T>>

export declare function getByTestId<T extends HTMLElement = HTMLElement>(
...args: Parameters<GetByBoundAttribute<T>>
): ReturnType<GetByBoundAttribute<T>>

export declare type GetByText<T extends HTMLElement = HTMLElement> = (
container: HTMLElement,
id: Matcher,
options?: SelectorMatcherOptions,
) => T

export declare function getByText<T extends HTMLElement = HTMLElement>(
...args: Parameters<GetByText<T>>
): ReturnType<GetByText<T>>

export declare function getByTitle<T extends HTMLElement = HTMLElement>(
...args: Parameters<GetByBoundAttribute<T>>
): ReturnType<GetByBoundAttribute<T>>

export declare function getConfig(): Config

export declare function getDefaultNormalizer(
options?: DefaultNormalizerOptions,
): NormalizerFn

export declare function getElementError(
message: string | null,
container: HTMLElement,
): Error

export declare type GetErrorFunction<Arguments extends any[] = [string]> = (
c: Element | null,
...args: Arguments
) => string

export declare function getNodeText(node: HTMLElement): string

export declare function getQueriesForElement<
QueriesToBind extends Queries = typeof queries,
// Extra type parameter required for reassignment.
T extends QueriesToBind = QueriesToBind,
>(element: HTMLElement, queriesToBind?: T): BoundFunctions<T>

export declare function getRoles(container: HTMLElement): {
    [index: string]: HTMLElement[]
}

export declare function getSuggestedQuery(
element: HTMLElement,
variant?: Variant,
method?: Method,
): Suggestion | undefined

/**
 * @public
 */
declare const initElementTree: () => {
    uniqueId2Element: Map<number, LynxElement>;
    root: LynxElement | undefined;
    countElement(element: LynxElement, parentComponentUniqueId: number): void;
    __CreatePage(_tag: string, parentComponentUniqueId: number): LynxElement;
    __CreateRawText(text: string): LynxElement;
    __GetElementUniqueID(e: LynxElement): number;
    __SetClasses(e: LynxElement, cls: string): void;
    __CreateElement(tag: string, parentComponentUniqueId: number): LynxElement;
    __CreateView(parentComponentUniqueId: number): LynxElement;
    __CreateScrollView(parentComponentUniqueId: number): LynxElement;
    __FirstElement(e: LynxElement): LynxElement;
    __CreateText(parentComponentUniqueId: number): LynxElement;
    __CreateImage(parentComponentUniqueId: number): LynxElement;
    __CreateWrapperElement(parentComponentUniqueId: number): LynxElement;
    __AddInlineStyle(e: HTMLElement, key: number, value: string): void;
    __AppendElement(parent: LynxElement, child: LynxElement): void;
    __SetCSSId(e: LynxElement[] | LynxElement, id: string, entryName?: string | undefined): void;
    __SetAttribute(e: LynxElement, key: string, value: any): void;
    __AddEvent(e: LynxElement, eventType: string, eventName: string, eventHandler: string | Record<string, any>): void;
    __GetEvent(e: LynxElement, eventType: string, eventName: string): {
        type: string;
        name: string;
        jsFunction: any;
    } | undefined;
    __SetID(e: LynxElement, id: string): void;
    __SetInlineStyles(e: LynxElement, styles: string | Record<string, string>): void;
    __AddDataset(e: LynxElement, key: string, value: string): void;
    __SetDataset(e: LynxElement, dataset: any): void;
    __SetGestureDetector(e: LynxElement, id: number, type: number, config: any, relationMap: Record<string, number[]>): void;
    __RemoveGestureDetector(e: LynxElement, id: number): void;
    __GetDataset(e: LynxElement): DOMStringMap;
    __RemoveElement(parent: LynxElement, child: LynxElement): void;
    __InsertElementBefore(parent: LynxElement, child: LynxElement, ref?: LynxElement | undefined): void;
    __ReplaceElement(newElement: LynxElement, oldElement: LynxElement): void;
    __FlushElementTree(): void;
    __UpdateListComponents(_list: LynxElement, _components: string[]): void;
    __UpdateListCallbacks(list: LynxElement, componentAtIndex: (list: LynxElement, listID: number, cellIndex: number, operationID: number, enable_reuse_notification: boolean) => void, enqueueComponent: (list: LynxElement, listID: number, sign: number) => void): void;
    __CreateList(parentComponentUniqueId: number, componentAtIndex: any, enqueueComponent: any): LynxElement;
    __GetTag(ele: LynxElement): string;
    __GetAttributeByName(ele: LynxElement, name: string): string | null;
    /** @internal */
    animationMap: Map<string, {
        element: LynxElement;
        state: string;
        keyframes?: any[];
        options?: any;
    }>;
    __ElementAnimate(element: LynxElement, args: [number, string, ...any[]]): void;
    clear(): void;
    toTree(): LynxElement | undefined;
    /**
     * Enter a list-item element at the given index.
     * It will load the list-item element using the `componentAtIndex` callback.
     *
     * @param e - The list element
     * @param index - The index of the list-item element
     * @param args - The arguments used to create the list-item element
     * @returns The unique id of the list-item element
     */
    enterListItemAtIndex(e: LynxElement, index: number, ...args: any[]): number;
    /**
     * Leave a list-item element.
     * It will mark the list-item element as unused using
     * the `enqueueComponent` callback, and the list-item element
     * will be reused in the future by other list-item elements.
     *
     * @param e - The list element
     * @param uiSign - The unique id of the list-item element
     */
    leaveListItem(e: LynxElement, uiSign: number): void;
    toJSON(): LynxElement | undefined;
    __GetElementByUniqueId(uniqueId: number): LynxElement | undefined;
    __GetPageElement(): LynxElement | undefined;
    __QuerySelector(e: LynxElement, cssSelector: string, _params: object): LynxElement | undefined;
};

/**
 * https://testing-library.com/docs/dom-testing-library/api-helpers#isinaccessible
 */
export declare function isInaccessible(element: Element): boolean

export declare function logDOM(
dom?: Element | HTMLDocument,
maxLength?: number,
options?: PrettyDOMOptions,
): void

export declare function logRoles(
container: HTMLElement,
options?: LogRolesOptions,
): string

export declare interface LogRolesOptions {
    hidden?: boolean
}

/**
 * Any Lynx Element, such as `view`, `text`, `image`, etc.
 *
 * {@link https://lynxjs.org/living-spec/index.html?ts=1743416098203#element%E2%91%A0 | Lynx Spec Reference}
 *
 * @public
 */
declare interface LynxElement extends HTMLElement {
    /**
     * The map of events bound to the element.
     */
    eventMap?: {
        [key: string]: any;
    };
    /**
     * The gestures bound to the element.
     */
    gesture?: {
        [key: string]: any;
    };
    /**
     * The cssId of the element
     */
    cssId?: string;
    /**
     * Returns the first child.
     *
     * {@link https://developer.mozilla.org/docs/Web/API/Node/firstChild | MDN Reference}
     */
    firstChild: LynxElement;
    /**
     * Returns the next sibling.
     *
     * {@link https://developer.mozilla.org/docs/Web/API/Node/nextSibling | MDN Reference}
     */
    nextSibling: LynxElement;
    /**
     * Returns the parent.
     *
     * {@link https://developer.mozilla.org/docs/Web/API/Node/parentNode | MDN Reference}
     */
    parentNode: LynxElement;
}

/**
 * The host environment used to initialize `LynxTestingEnv`.
 *
 * @public
 */
declare interface LynxEnv {
    window: Window & typeof globalThis;
}

/**
 * The `globalThis` object of Lynx dual thread environment.
 *
 * @public
 */
declare interface LynxGlobalThis {
    /**
     * The globalThis object.
     */
    globalThis: LynxGlobalThis;
    [key: string]: any;
}

/**
 * A pure-JavaScript implementation of the {@link https://lynxjs.org/guide/spec.html | Lynx Spec},
 * notably the {@link https://lynxjs.org/api/engine/element-api | Element PAPI} and {@link https://lynxjs.org/guide/spec#dual-threaded-model | Dual-threaded Model} for use with Node.js.
 *
 * @example
 *
 * ```ts
 * import { LynxTestingEnv } from '@lynx-js/testing-environment';
 * import { JSDOM } from 'jsdom';
 *
 * const lynxTestingEnv = new LynxTestingEnv({ window: new JSDOM().window });
 *
 * lynxTestingEnv.switchToMainThread();
 * // use the main thread Element PAPI
 * const page = __CreatePage('0', 0);
 * const view = __CreateView(0);
 * __AppendElement(page, view);
 *
 * ```
 *
 * @public
 */
export declare class LynxTestingEnv {
    private originals;
    /**
     * The global object for the background thread.
     *
     * @example
     *
     * ```ts
     * import { LynxTestingEnv } from '@lynx-js/testing-environment';
     * import { JSDOM } from 'jsdom';
     *
     * const lynxTestingEnv = new LynxTestingEnv({ window: new JSDOM().window });
     *
     * lynxTestingEnv.switchToBackgroundThread();
     * // use the background thread global object
     * globalThis.lynxCoreInject.tt.OnLifecycleEvent(...args);
     * ```
     */
    backgroundThread: LynxGlobalThis;
    /**
     * The global object for the main thread.
     *
     * @example
     *
     * ```ts
     * import { LynxTestingEnv } from '@lynx-js/testing-environment';
     * import { JSDOM } from 'jsdom';
     *
     * const lynxTestingEnv = new LynxTestingEnv({ window: new JSDOM().window });
     *
     * lynxTestingEnv.switchToMainThread();
     * // use the main thread global object
     * const page = globalThis.__CreatePage('0', 0);
     * const view = globalThis.__CreateView(0);
     * globalThis.__AppendElement(page, view);
     * ```
     */
    mainThread: LynxGlobalThis & ElementTreeGlobals;
    env: LynxEnv;
    constructor(env?: LynxEnv);
    injectGlobals(): void;
    switchToBackgroundThread(): void;
    switchToMainThread(): void;
    clearGlobal(): void;
    reset(): void;
}

export declare type Match = (
textToMatch: string,
node: HTMLElement | null,
matcher: Matcher,
options?: MatcherOptions,
) => boolean

export declare type Matcher = MatcherFunction | RegExp | number | string

export declare type MatcherFunction = (
content: string,
element: Element | null,
) => boolean

export declare interface MatcherOptions {
    exact?: boolean
    /** Use normalizer with getDefaultNormalizer instead */
    trim?: boolean
    /** Use normalizer with getDefaultNormalizer instead */
    collapseWhitespace?: boolean
    normalizer?: NormalizerFn
    /** suppress suggestions for a specific query */
    suggest?: boolean
}

export declare type Method =
| 'AltText'
| 'alttext'
| 'DisplayValue'
| 'displayvalue'
| 'LabelText'
| 'labeltext'
| 'PlaceholderText'
| 'placeholdertext'
| 'Role'
| 'role'
| 'TestId'
| 'testid'
| 'Text'
| 'text'
| 'Title'
| 'title'

export declare type NormalizerFn = (text: string) => string

export declare interface NormalizerOptions extends DefaultNormalizerOptions {
    normalizer?: NormalizerFn
}

/**
 * @public
 */
declare type PickUnderscoreKeys<T> = Pick<T, FilterUnderscoreKeys<T>>;

export declare function prettyDOM(
dom?: Element | HTMLDocument,
maxLength?: number,
options?: PrettyDOMOptions,
): string | false

export declare interface PrettyDOMOptions extends prettyFormat.OptionsReceived {
    /**
     * Given a `Node` return `false` if you wish to ignore that node in the output.
     * By default, ignores `<style />`, `<script />` and comment nodes.
     */
    filterNode?: (node: Node) => boolean
}

export { prettyFormat }

export declare interface Queries {
    [T: string]: Query
}

declare namespace queries {
    export {
        getByLabelText,
        getAllByLabelText,
        queryByLabelText,
        queryAllByLabelText,
        findByLabelText,
        findAllByLabelText,
        getByPlaceholderText,
        getAllByPlaceholderText,
        queryByPlaceholderText,
        queryAllByPlaceholderText,
        findByPlaceholderText,
        findAllByPlaceholderText,
        getByText,
        getAllByText,
        queryByText,
        queryAllByText,
        findByText,
        findAllByText,
        getByAltText,
        getAllByAltText,
        queryByAltText,
        queryAllByAltText,
        findByAltText,
        findAllByAltText,
        getByTitle,
        getAllByTitle,
        queryByTitle,
        queryAllByTitle,
        findByTitle,
        findAllByTitle,
        getByDisplayValue,
        getAllByDisplayValue,
        queryByDisplayValue,
        queryAllByDisplayValue,
        findByDisplayValue,
        findAllByDisplayValue,
        getByRole,
        getAllByRole,
        queryByRole,
        queryAllByRole,
        findByRole,
        findAllByRole,
        getByTestId,
        getAllByTestId,
        queryByTestId,
        queryAllByTestId,
        findByTestId,
        findAllByTestId,
        QueryByBoundAttribute,
        AllByBoundAttribute,
        FindAllByBoundAttribute,
        GetByBoundAttribute,
        FindByBoundAttribute,
        QueryByText,
        AllByText,
        FindAllByText,
        GetByText,
        FindByText,
        ByRoleOptions,
        AllByRole,
        GetByRole,
        QueryByRole,
        FindByRole,
        FindAllByRole
    }
}
export { queries }

export declare type Query = (
container: HTMLElement,
...args: any[]
) =>
| Error
| HTMLElement
| HTMLElement[]
| Promise<HTMLElement[]>
| Promise<HTMLElement>
| null

export declare function queryAllByAltText<T extends HTMLElement = HTMLElement>(
...args: Parameters<AllByBoundAttribute<T>>
): ReturnType<AllByBoundAttribute<T>>

export declare const queryAllByAttribute: AllByAttribute;

export declare function queryAllByDisplayValue<T extends HTMLElement = HTMLElement>(
...args: Parameters<AllByBoundAttribute<T>>
): ReturnType<AllByBoundAttribute<T>>

export declare function queryAllByLabelText<T extends HTMLElement = HTMLElement>(
...args: Parameters<AllByText<T>>
): ReturnType<AllByText<T>>

export declare function queryAllByPlaceholderText<T extends HTMLElement = HTMLElement>(
...args: Parameters<AllByBoundAttribute<T>>
): ReturnType<AllByBoundAttribute<T>>

export declare function queryAllByRole<T extends HTMLElement = HTMLElement>(
...args: Parameters<AllByRole<T>>
): ReturnType<AllByRole<T>>

export declare function queryAllByTestId<T extends HTMLElement = HTMLElement>(
...args: Parameters<AllByBoundAttribute<T>>
): ReturnType<AllByBoundAttribute<T>>

export declare function queryAllByText<T extends HTMLElement = HTMLElement>(
...args: Parameters<AllByText<T>>
): ReturnType<AllByText<T>>

export declare function queryAllByTitle<T extends HTMLElement = HTMLElement>(
...args: Parameters<AllByBoundAttribute<T>>
): ReturnType<AllByBoundAttribute<T>>

export declare type QueryArgs = [string, QueryOptions?]

export declare type QueryBy<Arguments extends any[]> = QueryMethod<
Arguments,
HTMLElement | null
>

export declare function queryByAltText<T extends HTMLElement = HTMLElement>(
...args: Parameters<QueryByBoundAttribute<T>>
): ReturnType<QueryByBoundAttribute<T>>

export declare type QueryByAttribute = (
attribute: string,
container: HTMLElement,
id: Matcher,
options?: MatcherOptions,
) => HTMLElement | null

export declare const queryByAttribute: QueryByAttribute;

export declare type QueryByBoundAttribute<T extends HTMLElement = HTMLElement> = (
container: HTMLElement,
id: Matcher,
options?: MatcherOptions,
) => T | null

export declare function queryByDisplayValue<T extends HTMLElement = HTMLElement>(
...args: Parameters<QueryByBoundAttribute<T>>
): ReturnType<QueryByBoundAttribute<T>>

export declare function queryByLabelText<T extends HTMLElement = HTMLElement>(
...args: Parameters<QueryByText<T>>
): ReturnType<QueryByText<T>>

export declare function queryByPlaceholderText<T extends HTMLElement = HTMLElement>(
...args: Parameters<QueryByBoundAttribute<T>>
): ReturnType<QueryByBoundAttribute<T>>

export declare type QueryByRole<T extends HTMLElement = HTMLElement> = (
container: HTMLElement,
role: ByRoleMatcher,
options?: ByRoleOptions,
) => T | null

export declare function queryByRole<T extends HTMLElement = HTMLElement>(
...args: Parameters<QueryByRole<T>>
): ReturnType<QueryByRole<T>>

export declare function queryByTestId<T extends HTMLElement = HTMLElement>(
...args: Parameters<QueryByBoundAttribute<T>>
): ReturnType<QueryByBoundAttribute<T>>

export declare type QueryByText<T extends HTMLElement = HTMLElement> = (
container: HTMLElement,
id: Matcher,
options?: SelectorMatcherOptions,
) => T | null

export declare function queryByText<T extends HTMLElement = HTMLElement>(
...args: Parameters<QueryByText<T>>
): ReturnType<QueryByText<T>>

export declare function queryByTitle<T extends HTMLElement = HTMLElement>(
...args: Parameters<QueryByBoundAttribute<T>>
): ReturnType<QueryByBoundAttribute<T>>

declare namespace queryHelpers {
    export {
        getElementError,
        buildQueries,
        WithSuggest,
        GetErrorFunction,
        SelectorMatcherOptions,
        QueryByAttribute,
        AllByAttribute,
        queryByAttribute,
        queryAllByAttribute,
        QueryMethod,
        QueryBy,
        GetAllBy,
        FindAllBy,
        GetBy,
        FindBy,
        BuiltQueryMethods
    }
}
export { queryHelpers }

/**
 * query methods have a common call signature. Only the return type differs.
 */
export declare type QueryMethod<Arguments extends any[], Return> = (
container: HTMLElement,
...args: Arguments
) => Return

export declare interface QueryOptions {
    [key: string]: RegExp | boolean
}

/**
 * Render into the page. It should be used with cleanup.
 *
 * @example
 *
 * ```ts
 * import { render} from '@lynx-js/react/testing-library'
 *
 * const WrapperComponent = ({ children }) => (
 *     <view data-testid='wrapper'>{children}</view>
 * );
 * const Comp = () => {
 *   return <view data-testid='inner' style="background-color: yellow;" />;
 * };
 * const { container, getByTestId } = render(<Comp />, {
 *   wrapper: WrapperComponent,
 * });
 * expect(getByTestId('wrapper')).toBeInTheDocument();
 * expect(container.firstChild).toMatchInlineSnapshot(`
 *   <view
 *     data-testid="wrapper"
 *   >
 *     <view
 *       data-testid="inner"
 *       style="background-color: yellow;"
 *     />
 *   </view>
 * `);
 * ```
 *
 * @public
 */
export declare function render<Q extends Queries>(
ui: React.ReactNode,
options?: RenderOptions<Q>,
): RenderResult<Q>;

/**
 * Allows you to render a hook within a test React component without having to
 * create that component yourself.
 *
 * @example
 *
 * ```ts
 * import { renderHook } from '@lynx-js/react/testing-library'
 *
 * const Context = createContext('default');
 * function Wrapper({ children }) {
 *   return <Context.Provider value='provided'>{children}</Context.Provider>;
 * }
 * const { result } = renderHook(
 *   () => {
 *     return useContext(Context);
 *   },
 *   {
 *     wrapper: Wrapper,
 *   },
 * );
 *
 * expect(result.current).toEqual('provided');
 * ```
 *
 * @public
 */
export declare function renderHook<Result, Props>(
render: (initialProps: Props) => Result,
options?: RenderHookOptions<Props>,
): RenderHookResult<Result, Props>;

/**
 * The options for {@link renderHook}
 *
 * @public
 */
export declare interface RenderHookOptions<Props> {
    /**
     * The argument passed to the renderHook callback. Can be useful if you plan
     * to use the rerender utility to change the values passed to your hook.
     */
    initialProps?: Props;
    /**
     * Pass a React Component as the wrapper option to have it rendered around the inner element. This is most useful for creating
     *  reusable custom render functions for common data providers. See setup for examples.
     *
     * @example
     *
     * ```ts
     * import { renderHook } from '@lynx-js/react/testing-library'
     * import { ThemeProvider } from 'my-ui-lib'
     * import { TranslationProvider } from 'my-i18n-lib'
     * import defaultStrings from 'i18n/en-x-default'
     *
     * const AllTheProviders = ({children}) => {
     *   return (
     *     <ThemeProvider theme="light">
     *       <TranslationProvider messages={defaultStrings}>
     *         {children}
     *       </TranslationProvider>
     *     </ThemeProvider>
     *   )
     * }
     *
     * const customRenderHook = (ui, options) =>
     *   renderHook(ui, { wrapper: AllTheProviders, ...options })
     *
     * // re-export everything
     * export * from '@lynx-js/react/testing-library'
     *
     * // override renderHook method
     * export { customRender as renderHook }
     * ```
     */
    wrapper?: React.JSXElementConstructor<{ children: React.ReactNode }> | undefined;
}

/**
 * The result of {@link renderHook}
 *
 * @public
 */

export declare interface RenderHookResult<Result, Props> {
    /**
     * Triggers a re-render. The props will be passed to your renderHook callback.
     */
    rerender: (props?: Props) => void;
    /**
     * This is a stable reference to the latest value returned by your renderHook
     * callback
     */
    result: {
        /**
         * The value returned by your renderHook callback
         */
        current: Result;
    };
    /**
     * Unmounts the test component. This is useful for when you need to test
     * any cleanup your useEffects have.
     */
    unmount: () => void;
}

/**
 * The options for {@link render}.
 *
 * @public
 */
export declare interface RenderOptions<Q extends Queries = typeof queries> {
    /**
     * Queries to bind. Overrides the default set from DOM Testing Library unless merged.
     *
     * @example
     *
     * ```ts
     * // Example, a function to traverse table contents
     * import * as tableQueries from 'my-table-query-library'
     * import { queries } from '@lynx-js/react/testing-library'
     *
     * const { getByRowColumn, getByText } = render(<MyTable />, {
     *   queries: {...queries, ...tableQueries},
     * })
     *
     * ```
     */
    queries?: Q;
    /**
     * Pass a React Component as the wrapper option to have it rendered around the inner element. This is most useful for creating
     *  reusable custom render functions for common data providers. See setup for examples.
     *
     * @example
     *
     * ```ts
     * import { render } from '@lynx-js/react/testing-library'
     * import { ThemeProvider } from 'my-ui-lib'
     * import { TranslationProvider } from 'my-i18n-lib'
     * import defaultStrings from 'i18n/en-x-default'
     *
     * const AllTheProviders = ({children}) => {
     *   return (
     *     <ThemeProvider theme="light">
     *       <TranslationProvider messages={defaultStrings}>
     *         {children}
     *       </TranslationProvider>
     *     </ThemeProvider>
     *   )
     * }
     *
     * const customRender = (ui, options) =>
     *   render(ui, { wrapper: AllTheProviders, ...options })
     *
     * // re-export everything
     * export * from '@lynx-js/react/testing-library'
     *
     * // override render method
     * export { customRender as render }
     * ```
     */
    wrapper?: React.JSXElementConstructor<{ children: React.ReactNode }> | undefined;
    /**
     * Render your component in the main thread or not.
     *
     * It is recommended to use this option only when you need to test the {@link https://lynxjs.org/zh/guide/interaction/ifr.html | IFR} behavior.
     *
     * @defaultValue false
     */
    enableMainThread?: boolean;
    /**
     * Render your component in the background thread or not.
     *
     * Note that all user code in the top level will be executed in the background thread by default. (eg. `__BACKGROUND__` is `true` in the top level)
     *
     * @defaultValue true
     */
    enableBackgroundThread?: boolean;
}

/**
 * The result of {@link render}
 *
 * @public
 */
export declare type RenderResult<Q extends Queries = typeof queries> = {
    container: LynxElement;
    rerender: (ui: React.ReactNode) => void;
    unmount: () => boolean;
    asFragment: () => DocumentFragment;
} & { [P in keyof Q]: BoundFunction<Q[P]> };

declare type Screen_2<Q extends Queries = typeof queries> = BoundFunctions<Q> & {
    /**
     * Convenience function for `pretty-dom` which also allows an array
     * of elements
     */
    debug: (
    element?: Array<Element | HTMLDocument> | Element | HTMLDocument,
    maxLength?: number,
    options?: OptionsReceived,
    ) => void
    /**
     * Convenience function for `Testing Playground` which logs and returns the URL that
     * can be opened in a browser
     */
    logTestingPlaygroundURL: (element?: Element | HTMLDocument) => string
}
export { Screen_2 as Screen }

declare const screen_2: Screen_2;
export { screen_2 as screen }

export declare interface SelectorMatcherOptions extends MatcherOptions {
    selector?: string
    ignore?: boolean | string
}

export declare interface Suggestion {
    queryName: string
    queryMethod: string
    queryArgs: QueryArgs
    variant: string
    warning?: string
    toString(): string
}

export declare type Variant =
| 'find'
| 'findAll'
| 'get'
| 'getAll'
| 'query'
| 'queryAll'

export declare function waitFor<T>(
callback: () => Promise<T> | T,
options?: waitForOptions,
): Promise<T>

export declare function waitForElementToBeRemoved<T>(
callback: T | (() => T),
options?: waitForOptions,
): Promise<void>

export declare interface waitForOptions {
    container?: HTMLElement
    timeout?: number
    interval?: number
    onTimeout?: (error: Error) => Error
    mutationObserverOptions?: MutationObserverInit
}

/**
 * Wait for the next event loop.
 *
 * It will be useful when you want to wait for the next event loop to finish.
 *
 * @deprecated Please use `act` instead
 */
export declare function waitSchedule(): Promise<void>;

export declare const within: typeof getQueriesForElement;

export declare type WithSuggest = {suggest?: boolean}

export { }
