/*!
 * Copyright 2019 VMware, Inc.
 * SPDX-License-Identifier: BSD-2-Clause
 */
import { DebugElement, Type } from '@angular/core';
import { ComponentFixture } from '@angular/core/testing';
/**
 * An implementation of the page object pattern, but applied to widgets, since they can be reused on multiple pages.
 *
 * The main purpose for the wrapper are providing access to the internals of a widget avoiding duplication of code that
 * queries the internals of a component from a test.
 *
 * ## Subclass Rules
 *
 * - Methods exposed by subclasses should not expose HTMLElements or DebugElements directly. That would encourage
 * callers to query it from the outside creating potential duplicate querying code and abstraction leaks.
 *  - Subclasses also should not have testing assertions. They should only provide the state and the calling test can
 * assert code on its own.
 *
 * `T` is the type of the JS/TS object being wrapped
 *
 * It is recommended that files for implementations be named with a `.wo.ts` extension
 *
 * @deprecated
 */
export declare abstract class WidgetObject<T> {
    protected fixture: ComponentFixture<any>;
    protected root: DebugElement;
    component: T;
    /**
     *
     * Constructor should only be called directly if you are directly instantiating the widget being wrapped (T). If you
     * need to find a widget within the tree, you should use {@link find}.
     *
     * @param component The component instance being managed. Whenever possible, we should access the component's API.
     * @param root The root element (host) for the component instance. We typically prefer to interact with the
     * component but there are times when we must check the DOM.
     * @param fixture The test fixture, so we can call {@link ComponentFixture#detectChanges} after something that
     * requires re-rendering of the DOM.
     */
    constructor(fixture: ComponentFixture<any>, root?: DebugElement, component?: T);
    detectChanges(): void;
    /**
     * Finds first element within this widget matching the given selector
     * @param selector What to search for
     * @param parent Where to start the search; defaults to the root of this component
     */
    protected findElement(selector: string | Type<unknown>, parent?: DebugElement): DebugElement;
    /**
     * Same as {@link findElement} but returns all elements
     */
    protected findElements(selector: string | Type<unknown>, parent?: DebugElement): DebugElement[];
    /**
     * Clicks an element and detects changes so the DOM is immediately updated
     * @param cssSelector Pass this in if you want to click a specific element. If not passed in, the entire node will
     * receive the click event
     * @param parent the parent element for which to search for the {@param cssSelector} within. Defaults to root if not provided.
     */
    protected click(cssSelector?: string, parent?: DebugElement): void;
    /**
     * Send a keyboard event of type {@param eventType} with properties {@param eventProperties} on an element
     * found by the {@param cssSelector} within the provided {@param parent} or the current root element.
     * Setting the event properties is done with `Object.defineProperty` on the created event. This allows setting
     * properties like `which` that is deprecated and cannot be set with the native approach of creating keyboard event.
     * @param eventType The keyboard event type like 'keyup', 'keydown', 'keypress'
     * @param eventProperties properties of the event like `code`, `key` etc.
     * @param cssSelector Pass this in if you want trigger the event on a specific element.
     *        If not passed in, the event will be triggered on the entire node
     * @param parent the parent element for which to search for the {@param cssSelector} within. Defaults to root if not provided.
     */
    protected sendKeyboardEvent(eventType: any, eventProperties: {
        [name: string]: unknown;
    }, cssSelector?: string, parent?: DebugElement): void;
    /**
     * Sets the value of an input element or textarea element
     * @param value the value that the element should display
     * @param cssSelector Pass this in if you want trigger the event on a specific element.
     *        If not passed in, the event will be triggered on the entire node
     * @param parent the parent element for which to search for the {@param cssSelector} within. Defaults to root if not provided.
     */
    protected setInputValue(value: string | number, cssSelector?: string, parent?: DebugElement): void;
    /**
     * Returns text content of this widget
     * If the element cannot be found, gives empty string.
     * @param cssSelector Pass this in if you want to retrieve text for a specific element within this widget.
     * @param parent Where to start the search; defaults to the root of this component
     */
    protected getText(cssSelector: string, parent?: DebugElement): string;
    /**
     * Same as {@link getText} but return the text for all matching nodes
     */
    protected getTexts(cssSelector: string): string[];
    protected getNodeText(el: DebugElement): string;
}
/**
 * Subclasses should implement the FindableWidget interface so they can be found with {@link WidgetFinder}
 *
 * ## Note
 * This is done by creating a static property `tagName`on your subclass, not a regular instance, since this
 * interface represents a constructor for a {@link WidgetObject}, not an instance.
 */
export interface FindableWidget<T> extends Type<T> {
    tagName: string;
}
/**
 * Arguments for {@link WidgetFinder#findWidgets} and {@link WidgetFinder#find}
 */
export interface FindParams<T> {
    /**
     * The constructor of the widget to be found
     */
    woConstructor: T;
    /**
     * If provided, search starts from this container. It defaults to the fixture's root debugElement
     */
    ancestor?: DebugElement;
    /**
     * Optional CSS class name that can be used when there could be multiple instances of the object within the
     * fixture tree
     */
    className?: string;
}
/**
 * @deprecated Finds instances that implement {@link FindableWidget}
 * H is the host component's type. This finder is only for old unit tests.
 * Please use AngularWidgetObjectFinder instead.
 */
export declare class WidgetFinder<H = unknown> {
    /**
     * We don't care or could possibly know the type of fixture
     */
    private fixture;
    /**
     * If you need direct access to manipulate the host
     */
    hostComponent: H;
    /**
     * @param componentConstructor The host component to be created as the root of the tests's fixture
     */
    constructor(componentConstructor: Type<H>);
    /**
     * Finds widgets within a fixture
     * @return A Potentially empty list of widgets matching the given specs
     */
    findWidgets<C, T extends FindableWidget<C>>(params: FindParams<T> | T, parent?: DebugElement): InstanceType<T>[];
    /**
     * Finds a single widget object
     * @throws An error if the widget is not found or if there are multiple instances
     */
    find<C, T extends FindableWidget<C>>(params: FindParams<T> | T): InstanceType<T>;
    detectChanges(): void;
}
export declare function isFindParamsObject<T>(params: FindParams<T> | T): params is FindParams<T>;
/**
 * Can be used in tests that use `this` to share a finder with before/AfterEach instead of leaky closures
 */
export interface HasFinder<T = unknown> {
    finder: WidgetFinder<T>;
}
