import debug from 'debug';
import { IAuthentication, Client, IUser } from '@c8y/client';
import { Har } from 'har-format';
import { ODiffOptions } from 'odiff-bin';

/**
 * Configuration options for `C8yPactPreprocessor`.
 *
 * All key-path strings support:
 * - Dot-separated segments: `response.body.password`
 * - Bracket / numeric-index notation: `response.body.items[0].token`
 * - Array fan-out: `response.body.users.password` (applied to every element)
 * - Recursive descent: `response.body..password` (any depth below `body`)
 *
 * Key resolution is case-insensitive when `ignoreCase` is `true` (default).
 */
interface C8yPactPreprocessorOptions {
    /**
     * Key paths whose values should be replaced with `obfuscationPattern`.
     *
     * For `Authorization` headers whose value begins with `Bearer` or `Basic`,
     * the scheme prefix is kept and only the credential token is replaced, e.g.
     * `Bearer ****`.
     *
     * Cookie values can be targeted by appending the cookie name as an extra
     * segment: `request.headers.cookie.XSRF-TOKEN`.
     *
     * @example
     * obfuscate: [
     *   "response.body.password",
     *   "request.headers.authorization",
     *   "response.body.users.password",   // every user object
     *   "response.body..token",           // any depth
     * ]
     */
    obfuscate?: string[];
    /**
     * Key paths whose values should be deleted entirely from the record.
     *
     * Cookie values can be targeted by appending the cookie name as an extra
     * segment: `request.headers.cookie.XSRF-TOKEN`.
     *
     * @example
     * ignore: [
     *   "request.headers.accept-encoding",
     *   "response.headers.cache-control",
     *   "response.body..internalDebugField",  // any depth
     * ]
     */
    ignore?: string[];
    /**
     * Restricts which child keys are retained under the specified parent paths.
     * All other sibling keys are removed.
     *
     * Two forms are accepted:
     *
     * **Object form** — maps a parent key path to an array of child keys to keep:
     * ```ts
     * pick: {
     *   "response.headers": ["content-type", "location"],
     *   "request.headers":  ["authorization"]
     * }
     * ```
     *
     * **Array form** — keeps only the listed top-level keys of the record:
     * ```ts
     * pick: ["request", "response"]
     * ```
     */
    pick?: {
        [key: string]: string[];
    } | string[];
    /**
     * Applies one or more regex substitutions to the value at the given key path.
     *
     * The key is a key path (same syntax as `obfuscate` / `ignore`). The value
     * is a single regex string or an ordered array of regex strings applied in
     * sequence. Each regex string must use the format:
     * ```
     * /pattern/replacement/flags
     * ```
     * Capture groups (`$1`, `$2`, …) and all standard JS regex flags are
     * supported.
     *
     * @example
     * // Redact all but the first four characters of a token:
     * // key:   "response.body.token"
     * // value: "/^(.{4}).+$/$1----/"
     * //
     * // Normalise a date field, then strip milliseconds in sequence:
     * // key:   "response.body.timestamp"
     * // value: ["/T\\d{2}:\\d{2}:\\d{2}/THH:MM:SS/", "/\\.\\d+Z$/Z/"]
     */
    regexReplace?: {
        [key: string]: string | string[];
    };
    /**
     * Replacement string used by the `obfuscate` operation.
     * Defaults to `"****"`.
     */
    obfuscationPattern?: string;
    /**
     * When `true` (default), key segments are matched case-insensitively at
     * every level of the path. The actual casing of the key found in the object
     * is always used for mutations — the original structure is never changed.
     */
    ignoreCase?: boolean;
}

type C8yPactAuthObject = {
    user: string;
    userAlias?: string;
    type?: string;
    token?: string;
} | {
    userAlias: string;
    user?: string;
    type?: string;
    token?: string;
};

/**
 * Matcher for matching objects against a schema. If the object does not match
 * the schema an Error will be thrown.
 */
interface C8ySchemaMatcher {
    /**
     * Matches the given object against the given schema. Throws an error when
     * schema does not match. Strict matching controls whether additional properties
     * are allowed in the object.
     *
     * @param obj Object to match.
     * @param schema Schema to match obj against.
     * @param strictMatching If true, additional properties are not allowed.
     */
    match(obj: any, schema: any, strictMatching?: boolean): boolean;
}

/**
 * Tenant ID of a Cumulocity tenant.
 * @example t123456
 */
type C8yTenant = string;
/**
 * Base URL of a Cumulocity tenant.
 * @example https://tenant.eu-latest.cumulocity.com
 */
type C8yBaseUrl = string;
interface C8yHighlightOptions {
    /**
     * The border style. Use any valid CSS border style. If provided an object, keys override the default border style.
     * @examples ["1px solid red"]
     */
    border?: string | any;
    /**
     * The CSS styles to apply to the DOM element. Use any valid CSS styles.
     * @examples [["background-color: yellow", "outline: dashed", "outline-offset: +3px"]]
     */
    styles?: any;
    /**
     * Overwrite the width of the highlighted element. If smaller than 1, the value is used as percentage of the element width.
     */
    width?: number;
    /**
     * Overwrite the height of the highlighted element. If smaller than 1, the value is used as percentage of the element height.
     */
    height?: number;
    /**
     * If true, existing highlights will be cleared before highlighting. The default is false.
     * @default false
     */
    clear?: boolean;
    /**
     * If true, the highlight is applied to all elements in the selection. The default is false.
     * @default false
     */
    multiple?: boolean;
    /**
     * If true, the highlight styles are applied to a detached <div> element instead of the target element. This is done automatically for elements with rounded corners or disabled elements to avoid visual issues. Use detached:true to force detached highlights.
     * @default false
     */
    detached?: boolean;
}

/**
 * Options used to configure c8yclient command.
 */
type C8yClientOptions = Partial<Cypress.Loggable> & Partial<Cypress.Timeoutable> & Partial<Pick<Cypress.Failable, "failOnStatusCode">> & Partial<{
    auth: IAuthentication;
    baseUrl: C8yBaseUrl;
    client: Client;
    preferBasicAuth: boolean;
    skipClientAuthentication: boolean;
    failOnPactValidation: boolean;
    ignorePact: boolean;
    schema: any;
    matchSchemaAndObject: boolean;
    record: C8yPactRecord;
    schemaMatcher: C8ySchemaMatcher;
    strictMatching: boolean;
    /** Custom ID to identify this request in logs. If not provided, a unique ID will be generated. */
    requestId: string;
}>;

declare const C8yPactRecordingModeValues: readonly ["refresh", "append", "new", "replace"];
/**
 * The pact recording mode is used to determine how or if requests and responses are recorded.
 * - `refresh` (default): Recreates the pact file with the all requests and responses.
 * - `append`: Appends the new requests and responses to the existing pact file.
 * - `new`: Only creates a new pact file if no pact file exists. If pact file exists, only new requests and responses are added.
 * - `replace`: Overwrites existing records of a pact with new request and response in the order of occurence. Other records are kept as is.
 */
type C8yPactRecordingMode = (typeof C8yPactRecordingModeValues)[number];
/**
 * ID representing a pact object. Should be unique.
 * @example api__get__permission_failure_tests
 */
type C8yPactID = string;
interface C8yPactRequestMatchingOptions {
    ignoreUrlParameters?: string[];
    baseUrl?: C8yBaseUrl;
}
interface C8yPactConfigOptions {
    /**
     * ID representing a pact object.
     */
    id?: C8yPactID;
    /**
     * Use to enable additional logging.
     */
    log?: boolean;
    /**
     * Information describing the producer of the pact. Includes name and version information
     */
    producer?: {
        name: string;
        version?: string;
    } | string;
    /**
     * Information describing the consumer of the pact. Includes name and version information
     */
    consumer?: {
        name: string;
        version?: string;
    } | string;
    /**
     * Tags describing the pact.
     */
    tags?: string[];
    /**
     * Description of the pact.
     */
    description?: string;
    /**
     * Use ignore to disable the pact for the current test case.
     */
    ignore?: boolean;
    /**
     * Use failOnMissingPacts to disable failing the test if no pact or no next record
     * is found for the current test case.
     */
    failOnMissingPacts?: boolean;
    /**
     * Use strictMatching to enable strict matching of the pact records. If strict matching
     * is enabled, all properties of the pact records must match and tests fail if a property
     * is missing. Default is false.
     */
    strictMatching?: boolean;
    /**
     * If strictMocking is enabled, an error will be thrown if no pact record matches the
     * current request. If disabled, the request will be passed through to the configured baseUrl.
     */
    strictMocking?: boolean;
    /**
     * Options to configure the C8yPactPreprocessor.
     *
     * The preprocessor runs on every pact record when it is saved (recording mode)
     * and before it is matched against any other record. Use it to remove or obfuscate
     * sensitive values before they reach the fixture file, or to sanitize
     * response bodies before they are compared.
     *
     * **Key-path syntax**
     *
     * All option values that accept key paths use dot-separated segments:
     * ```
     * response.body.password
     * request.headers.Authorization
     * ```
     * Bracket notation and numeric indices are also supported and the style is
     * preserved in output:
     * ```
     * response.body.items[0].token   // bracket style
     * response.body.items.0.token    // dot style
     * ```
     * When a segment resolves to an **array of objects** and the next segment is
     * not a numeric index, the operation is applied to every element of that
     * array automatically:
     * ```
     * response.body.users.password   // obfuscates `password` in every user object
     * ```
     *
     * **Recursive-descent operator (`..`)**
     *
     * Prefix the leaf key with `..` to apply the operation at any nesting depth
     * below the current node (or below the optional prefix path):
     * ```
     * ..password                       // find `password` anywhere in the record
     * response.body..password          // find `password` anywhere inside body
     * ```
     *
     * **Case-insensitive matching**
     *
     * Set `ignoreCase: true` (the default) to resolve keys without regard to
     * capitalization. The resolved casing of the actual object key is used for
     * all mutations, so the original structure is never corrupted.
     *
     * **Cookie / Set-Cookie shorthand**
     *
     * Append the cookie name as an extra segment to operate on a single cookie
     * rather than the entire header string:
     * ```
     * request.headers.cookie.XSRF-TOKEN
     * response.headers.set-cookie.authorization
     * ```
     *
     * @example
     * // Remove non-essential headers, obfuscate credentials, redact a token
     * preprocessor: {
     *   ignore:    ["response.headers.cache-control"],
     *   obfuscate: ["request.headers.authorization", "response.body..password"],
     *   regexReplace: {
     *     // keep only the first 4 chars, e.g. "abcd----"
     *     "response.body.token": "/^(.{4}).+$/$1----/"
     *   }
     * }
     */
    preprocessor?: C8yPactPreprocessorOptions;
    /**
     * Options to configure the C8yPact request matching.
     */
    requestMatching?: C8yPactRequestMatchingOptions;
    /**
     * Recording mode for the pact. Default is `refresh`.
     */
    recordingMode?: C8yPactRecordingMode;
    /**
     * When set to true, both schema validation and pact object matching are performed
     * when a schema is provided to cy.c8yclient. By default only schema validation runs
     * when a schema is provided. Default is false.
     */
    matchSchemaAndObject?: boolean;
}
interface C8yPactObject {
    /**
     * Pact records containing the requests and responses as well as auth information,
     * configuration options and created objects.
     */
    records: C8yPactRecord[];
    /**
     * Meta information describing the pact.
     */
    info: C8yPactInfo;
    /**
     * Unique id of the pact.
     */
    id: C8yPactID;
}
/**
 * Pact object. Contains all information about a recorded pact, including
 * the pact records with requests and responses as well as info object with
 * meta data. A C8yPact objtect must have an unique id.
 */
interface C8yPact extends C8yPactObject {
    /**
     * Clears all records of the pact. Also resets all indexes internally used for
     * iterating over the records.
     */
    clearRecords(): void;
    /**
     * Appends a new record to the pact. If skipIfExists is true, the record is
     * only appended if no record with the same request exists.
     * @param record The record to add.
     * @param skipIfExists If true, the record is only appended if no record for the same request exists.
     * @returns True if the record was appended, false otherwise.
     */
    appendRecord(record: C8yPactRecord, skipIfExists?: boolean): boolean;
    /**
     * Replaces an existing record with a new record. If no record with the same
     * request exists, the record is appended.
     * @param record The record to be replaced.
     * @returns True if the record was replaced, false otherwise.
     */
    replaceRecord(record: C8yPactRecord): boolean;
    /**
     * Returns the next pact record or null if no more records are available.
     * If an id is provided, the record is looked up by requestId or record id
     * and the cursor is advanced to the position after the matched record.
     * If no id is provided, the next record by sequential index is returned.
     */
    nextRecord(id?: string): C8yPactRecord | null;
    /**
     * Returns the next pact record matching the given request. Request matching is
     * based ob criteria like url and method. Returns null if no record is found.
     */
    nextRecordMatchingRequest(request: Partial<Request> | {
        url: string;
        method: string;
    }, baseUrl?: C8yBaseUrl): C8yPactRecord | null;
    /**
     * Returns an iterator for the pact records.
     */
    [Symbol.iterator](): Iterator<C8yPactRecord | null>;
}
/**
 * Meta information describing a pact and how it was recorded.
 */
interface C8yPactInfo extends C8yPactConfigOptions {
    id: C8yPactID;
    /**
     * Version information of the system, runner and pact standard used to record the pact.
     */
    version?: {
        system?: string;
        shell?: string;
        shellName?: string;
        c8ypact?: string;
        runner?: string;
    };
    /**
     * Title of the pact. Title is an array of suite and test titles.
     */
    title?: string[];
    /**
     * Base URL when recording the pact.
     */
    baseUrl: C8yBaseUrl;
    /**
     * Tenant when recording the pact.
     */
    tenant?: C8yTenant;
}
/**
 * The request stored in a C8yPactRecord.
 */
type C8yPactRequest = Partial<Cypress.RequestOptions> & {
    $body?: any;
};
/**
 * The response stored in a C8yPactRecord.
 */
interface C8yPactResponse<T> {
    allRequestResponses?: any[];
    body?: T;
    duration?: number;
    headers?: {
        [key: string]: string | string[];
    };
    isOkStatusCode?: boolean;
    status?: number;
    statusText?: string;
    method?: string;
    $body?: any;
}
/**
 * The C8yPactRecord contains all information about a recorded request. It contains
 * the request and response as well as configuration options, auth information and
 * the created object id.
 */
interface C8yPactRecord {
    /**
     * Unique id of the record. Optional.
     */
    id?: C8yPactID;
    /**
     * Request of the record.
     */
    request: C8yPactRequest;
    /**
     * Response of the record.
     */
    response: C8yPactResponse<any>;
    /**
     * Modified response returned by interception RouteHandler.
     */
    modifiedResponse?: C8yPactResponse<any>;
    /**
     * Configuration options used for the request.
     */
    options?: C8yClientOptions;
    /**
     * Auth information used for the request. Can be Basic or Cookie auth. Contains username and possibly alias.
     */
    auth?: C8yPactAuthObject;
    /**
     * Id of an object created by the request. Used for mapping when running the recording.
     */
    createdObject?: string;
    /**
     * Converts the C8yPactRecord to a Cypress.Response object.
     */
    toCypressResponse(): Cypress.Response<any>;
    /**
     * Returns the date of the response.
     */
    date(): Date | null;
    /**
     * Returns if the record has a request header with the given key. Comparison is case-insensitive.
     */
    hasRequestHeader(key: string): boolean;
    /**
     * Returns the auth type of the record. Currently supports `BasicAuth`, `CookieAuth` or undefined.
     */
    authType(): "BasicAuth" | "CookieAuth" | "BearerAuth" | undefined;
}
type C8yPactSaveKeys = "id" | "info" | "records";

interface C8yPactAdapterOptions {
    /** Enable loading of JavaScript pact files (.js, .cjs). Defaults to false. */
    enableJavaScript?: boolean;
    /** Optional id to use for example for logging purposes. */
    id?: string;
}
/**
 * Using C8yPactFileAdapter you can implement your own adapter to load and save pacts using any format you want.
 * This allows loading pact objects from different sources, such as HAR files, pact.io, etc.
 *
 * The default adapter is C8yPactDefaultFileAdapter which loads and saves pact objects from/to
 * json files using C8yPact objects. Default location is cypress/fixtures/c8ypact folder.
 *
 * Alternative adapters:
 * - C8yPactHARFileAdapter: Reads/writes HAR (HTTP Archive) format for use with external tools
 */
interface C8yPactFileAdapter {
    /**
     * Loads all pact objects. The key must be the pact id used in C8yPact.id.
     */
    loadPacts: () => {
        [key: string]: C8yPactObject;
    };
    /**
     * Loads a pact object by id from file.
     */
    loadPact: (id: string) => C8yPactObject | null;
    /**
     * Saves a pact object.
     */
    savePact: (pact: C8yPactObject) => void;
    /**
     * Deletes a pact object or file.
     */
    deletePact: (id: string) => void;
    /**
     * Gets the folder where the pact files are stored.
     */
    getFolder: () => string;
    /**
     * Checks if a pact exists for a given id.
     */
    pactExists(id: string): boolean;
    /**
     * Provides some custom description of the adapter.
     * @example C8yPactFileAdapter
     */
    description(): string;
}
/**
 * Default implementation of C8yPactFileAdapter which loads and saves C8yPact objects
 * Provide location of the files using folder option. Default location is
 * cypress/fixtures/c8ypact folder.
 *
 * This adapter supports loading of JSON and YAML pact files (.json, .yaml, .yml). When
 * saviing pact files, it saves them as JSON files (.json).
 *
 * By using C8yPactAdapterOptions you can enable loading of JavaScript pact files (.js, .cjs).
 * Use with caution, as this can lead to security issues if the files are not trusted.
 */
declare class C8yPactDefaultFileAdapter implements C8yPactFileAdapter {
    folder: string;
    protected enabledExtensions: string[];
    protected fileExtension: string;
    protected readonly id: string;
    protected readonly log: debug.Debugger;
    /**
     * Creates an instance of C8yPactDefaultFileAdapter.
     *
     * @param folder - The folder where pact files are stored. Can be an absolute or relative path.
     * @param options - Optional configuration for the adapter.
     * @param options.enableJavaScript - If true, enables loading of JavaScript pact files (.js, .cjs). Defaults to false.
     */
    constructor(folder: string, options?: C8yPactAdapterOptions);
    description(): string;
    getFolder(): string;
    loadPacts(): {
        [key: string]: C8yPactObject;
    };
    loadPact(id: string): C8yPactObject | null;
    pactExists(id: string): boolean;
    savePact(pact: C8yPactObject | Pick<C8yPactObject, C8yPactSaveKeys>): void;
    deletePact(id: string): void;
    readPactFiles(): string[];
    /**
     * @deprecated Use readPactFiles() instead.
     */
    readJsonFiles(): string[];
    protected deleteJsonFiles(): void;
    protected loadPactObjects(): (C8yPactObject | null)[];
    protected loadPactFromFile(filePath: string): C8yPactObject | null;
    protected createFolderRecursive(f: string): string | undefined;
    protected toAbsolutePath(f: string): string;
    protected isNodeError<T extends new (...args: any) => Error>(error: any, type: T): error is InstanceType<T> & NodeJS.ErrnoException;
}

/**
 * C8yPactHARFileAdapter converts between C8yPact format and HAR (HTTP Archive) format.
 * This allows using external HAR tooling with C8yPact recordings.
 *
 * This adapter extends C8yPactDefaultFileAdapter to reuse folder management and utility
 * methods, but only supports .har file extension for reading and writing.
 *
 * When saving, pacts are converted to HAR format. When loading, HAR files are converted
 * back to C8yPact format. Some metadata may be stored in the comment fields to preserve
 * C8yPact-specific information.
 */
declare class C8yPactHARFileAdapter extends C8yPactDefaultFileAdapter {
    protected readonly id: string;
    constructor(folder: string);
    description(): string;
    savePact(pact: C8yPact | Pick<C8yPact, C8yPactSaveKeys>): void;
    /**
     * Override parent's loadPactFromFile to handle HAR format conversion.
     * This is called by parent's loadPactObjects for each .har file found.
     */
    protected loadPactFromFile(filePath: string): C8yPactObject | null;
    /**
     * Override parent's loadPactObjects to use simpler glob pattern for .har files.
     * The parent's brace expansion pattern doesn't work well with single extensions.
     */
    protected loadPactObjects(): C8yPact[];
    /**
     * Convert a C8yPact object to HAR format
     */
    protected pactToHAR(pact: C8yPact): Har;
    /**
     * Convert a HAR format to C8yPact object
     */
    protected harToPact(har: Har, id: string): C8yPactObject | null;
}

type ScreenshotSetup = {
    /**
     * The base URL used for all relative requests.
     * @format uri
     */
    baseUrl?: C8yBaseUrl;
    /**
     * The title used for root group of screenshot workflows
     */
    title?: string;
    /**
     * The global settings for all screenshots
     */
    global?: GlobalOptions & ScreenshotSettings & ScreenshotOptions;
    /**
     * Definition of shared selectors to use in the screenshot workflows
     */
    selectors?: SharedSelector | SharedSelector[];
    /**
     * The screenshot workflows
     */
    screenshots: (Screenshot & ScreenshotOptions)[];
};
interface GlobalOptions {
    /**
     * The selector to wait for when visiting a page
     * @default "c8y-drawer-outlet c8y-app-icon .c8y-icon"
     * @examples ["c8y-drawer-outlet c8y-app-icon .c8y-icon"]
     */
    visitWaitSelector?: string;
    /**
     * The defaulft style to highlight elements. By default, an organge border of 2px width is used to highlight elements.
     * @examples [{ "outline": "2px", "outline-style": "solid", "outline-offset": "-2px", "outline-color": "#FF9300" }, { "border": "2px solid red" }]
     */
    highlightStyle?: any;
}
type SemverRange = string;
type UserType = Partial<Pick<IUser, "userName" | "firstName" | "lastName" | "email" | "phone" | "id" | "displayName">>;
interface ScreenshotOptions {
    /**
     * Tags allow grouping and filtering of screenshots (optional)
     */
    tags?: string[];
    /**
     * The shell is used to dermine the version of the application used by "requires" (optional)
     * @examples ["cockpit, devicemanagement, oee"]
     */
    shell?: string;
    /**
     * Requires the shell application to have the a version in the given range. The range must be a valid semver range. If requires is configured and shell version does not fullfill the version requirement, the screenshot workflow will be skipped.
     * @format semver-range
     * @examples ["1.x, ^1.0.0, >=1.0.0 <2.0.0"]
     */
    requires?: SemverRange;
    /**
     * Load Cumulocity with the given language
     * @example "en"
     */
    language?: "en" | "de" | string | string[];
    /**
     * A user object with properties used to mock the user information in Cumulocity. This is useful to anonymize the user information in the screenshots.
     */
    user?: string | UserType;
    /**
     * The alias referencing the username and password to login. Configure the username and password using *login*_username and *login*_password env variables. If set to false, login is disabled and visit is performed unauthenticated.
     * @examples [["admin", false]]
     */
    login?: string | false;
    /**
     * The date to simulate when running the screenshot workflows
     * @format date-time
     * @examples ["2024-09-26T19:17:35+02:00"]
     */
    date?: string;
    /**
     * Viewport position to which an element should be scrolled before executing commands. The default is false.
     * @default false
     */
    scrollBehavior?: "center" | "top" | "bottom" | "nearest" | false;
}
interface Screenshot {
    /**
     * The name of the screenshot image as relative path
     * @examples ["/images/cockpit/dashboard.png"]
     */
    image: string;
    /**
     * The title of the screenshot workflow. The title is used to group the screenshots. To provide a hierarchy of titles, use an array of strings.
     */
    title?: string | string[];
    /**
     * The URI to visit. This typically a relative path to the baseUrl.
     * @examples ["/apps/cockpit/index.html#/"]
     */
    visit: string | Visit;
    /**
     * The actions to perform in the screenshot workflow. The last actioncis always a screenshot action. If no actions are defined or last actions is not a screenshot action, a screenshot is taken of the current state of the application.
     */
    actions?: Action[] | Action;
    /**
     * Run only this screenshot workflow and all other workflows that have only setting enabled
     */
    only?: boolean;
    /**
     * Skip this screenshot workflow
     */
    skip?: boolean;
    /**
     * The configuration and settings of the screenshot
     */
    settings?: ScreenshotSettings;
}
interface ScreenshotSettings {
    /**
     * The width in px to use for the browser window
     * @minimum 0
     * @default 1440
     * @TJS-type integer
     */
    viewportWidth?: number;
    /**
     * The height in px to use for the browser window
     * @minimum 0
     * @default 900
     * @TJS-type integer
     */
    viewportHeight?: number;
    /**
     * The capturing type for the screenshot. When 'fullPage' is used, the application is captured in its entirety from top to bottom. Setting is ignored when screenshots are taken for a selected DOM element. The default is 'viewport'.
     * Note that 'fullPage' screenshots will have a different height than specified in 'viewportHeight'.
     * @examples [["viewport", "fullPage"]]
     * @default "viewport"
     */
    capture?: "viewport" | "fullPage";
    /**
     * The padding in px used to alter the dimensions of a screenshot of an element.
     * @minimum 0
     * @TJS-type integer
     */
    padding?: number;
    /**
     * Whether to scale the app to fit into the browser viewport.
     */
    scale?: boolean;
    /**
     * Overwrite existing screenshots. By enabling this setting, existing screenshots might be deleted before running the screenshot workflow.
     */
    overwrite?: boolean;
    /**
     * When true, prevents JavaScript timers (setTimeout, setInterval, etc) and CSS animations from running while the screenshot is taken.
     */
    disableTimersAndAnimations?: boolean;
    /**
     * Options to configure the diffing of screenshots.
     */
    diff?: ForwardedOdiffOptions;
    /**
     * The timeouts supported by Cypress.
     */
    timeouts?: {
        /**
         * The time, in milliseconds, to wait until most DOM based commands are considered timed out.
         * @examples [10000]
         * @default 4000
         * @TJS-type integer
         */
        default?: number;
        /**
         * The time, in milliseconds, to wait for the page to load. This is used for visit actions.
         * @examples [30000]
         * @default 60000
         * @TJS-type integer
         */
        pageLoad?: number;
        /**
         * The time, in milliseconds, to wait for a response from a network request. Also applies to screenshot action.
         * @examples [60000]
         * @default 30000
         * @TJS-type integer
         */
        screenshot?: number;
    };
}
interface ForwardedOdiffOptions extends Pick<ODiffOptions, "threshold" | "ignoreRegions" | "antialiasing" | "diffColor" | "outputDiffMask"> {
}
interface Visit {
    /**
     * The URL to visit. Currently only an URI relative to the base URL is supported.
     * @format uri-reference
     */
    url: string;
    /**
     * The timeout in ms to wait for the page to load.
     * @examples [30000]
     * @TJS-type integer
     */
    timeout?: number;
    /**
     * The selector to wait for before taking the screenshot.
     * @examples ["c8y-drawer-outlet c8y-app-icon .c8y-icon"]
     */
    selector?: string;
}
interface ClickAction {
    /**
     * If true, the click event is triggered on all matching elements. The default is false.
     * @default false
     */
    multiple?: boolean;
    /**
     * If true, the click event is triggered even if the element is not visible. The default is false.
     * @default false
     */
    force?: boolean;
}
type CyPositionType = "topLeft" | "top" | "topRight" | "left" | "center" | "right" | "bottomLeft" | "bottom" | "bottomRight";
interface ScrollToAction {
    /**
     * The element to scroll to. Requires a selector or a DOM element. If the element is not visible, the page is scrolled to make the element visible.
     * The offset is applied when the element has been scrolled into view. The offset represents left and right pixel to scroll.
     */
    element?: string | ({
        offset?: [number, number];
    } & Selectable);
    /**
     * The position to scroll to. The default is 'top'. Provide a string, an array of strings, or a number to scroll to a specific position.
     * @examples ["top", "bottom", ["top", "100px"], [0, 100], ["0%", "25%"]]
     */
    position?: CyPositionType | [string, string] | [number, number];
}
interface TypeAction {
    /**
     * The value to type into the selected DOM element. The value can be a string or an array of strings. If an array is provided, textfields within the selector are filled with the values in the array.
     *
     * For multistep forms, the value can be an array of strings. Each array represents a step in the form. The first value in the array is typed into the first textfield, the second value in the second textfield, and so on. Configure submit selector to continue to the next step of the form.
     */
    value: string | (string | null)[] | (string | null)[][];
    /**
     * If true, the text input is cleared before typing. The default is false.
     * @default false
     */
    clear?: boolean;
    /**
     * If true, the element is blurred after typing to remove the focus. The default is false.
     * @default false
     */
    blur?: boolean;
    /**
     * The submit selector is triggered for every entry value. Use to go over multistep forms. If the submit selector is not found, the form is not automatically continued and multistep finishes.
     */
    submit?: string | Selectable;
}
interface TextAction {
    /**
     * The value to set
     */
    value: string;
}
interface WaitAction {
    /**
     * The timeout in ms to wait for
     * @TJS-type integer
     * @default 4000
     */
    timeout?: number;
    /**
     * The chainer assertion to wait for. This translates to a Cypress get().should().
     * See https://docs.cypress.io/api/commands/should
     */
    assert?: string | {
        /**
         * The chainer assertion to. Could be any valid Cypress chainer. The chainer is not validated and may or may not have a value to assert.
         * @examples ["have.length", "eq", "be.visible"]
         */
        chainer: string;
        /**
         * The value to assert. The value is optional and may not be required by the chainer assertion.
         */
        value?: string | string[];
    };
}
interface UploadFileAction {
    /**
     * The path to the file to upload. Resolve the file path relative to the current working directory. Currently, only a single file of types .json, .txt, .csv, .png, .jpg, .jpeg, .gif can be uploaded. If file does not have required extension, overwrite extension in the fileName property.
     */
    file: string;
    /**
     * The name of the file to use when uploading including file extension. If not provided, the file name is determined from the file path.
     * @examples ["file.txt"]
     */
    fileName?: string;
    /**
     * The encoding of the file. If not provided, the encoding is determined automatically. Default is 'utf8' or 'binary' depending of file extension.
     * @examples [["binary", "utf8"]]
     */
    encoding?: "binary" | "utf8" | "utf-8";
    /**
     * The type of the file input element. The default is 'input'.
     * @default "input"
     */
    subjectType?: "input" | "drag-n-drop";
    /**
     * If true, the file is uploaded even if the element is not visible. The default is false.
     * @default false
     */
    force?: boolean;
    /**
     * The MIME type of the file. If not provided, the MIME type is determined automatically.
     * @examples ["application/json", "text/csv", "image/png"]
     */
    mimeType?: string;
}
interface HighlightAction extends C8yHighlightOptions {
    /**
     * The outline offset. The default is -2px.
     */
    offset?: string;
}
type SelectableHighlightAction = HighlightAction & Selectable;
interface ScreenshotClipArea {
    /**
     * The x-coordinate of the top-left corner of the clip area
     * @minimum 0
     * @TJS-type integer
     */
    x: number;
    /**
     * The y-coordinate of the top-left corner of the clip area
     * @minimum 0
     * @TJS-type integer
     */
    y: number;
    /**
     * The width of the clip area. If negative, the width is subtracted from the viewport width.
     * @TJS-type integer
     */
    width: number;
    /**
     * The height of the clip area. If negative, the height is subtracted from the viewport height.
     * @TJS-type integer
     */
    height: number;
}
interface ScreenshotAction {
    /**
     * The path to store the screenshot. This is the relative path used within the screenshot folder.
     */
    path?: string;
    /**
     * The clip area within the screenshot image. The clip area is defined by the top-left corner (x, y) and the width and height of the clip area.
     */
    clip?: ScreenshotClipArea;
    /**
     * The padding applied to the screenshots of elements in px. If an array of numbers is provided, the padding is applied as defined by CSS shorthand property.
     */
    padding?: number | [number] | [number, number] | [number, number, number] | [number, number, number, number];
}
interface Action {
    /**
     * A blur action triggers a blur event on the selected DOM element to remove focus.
     */
    blur?: string | Selectable | true;
    /**
     * A click action triggers a click event on the selected DOM element.
     */
    click?: string | (ClickAction & Selectable);
    /**
     * Use the file upload action to upload a file using the file input element. Currently supported file types are .json, .txt, .csv, .png, .jpg, .jpeg, .gif.
     */
    fileUpload?: string | (UploadFileAction & Selectable);
    /**
     * A focus action triggers a focus event on the selected DOM element.
     */
    focus?: string | Selectable;
    /**
     * Use highlight action to visually highlight a selected DOM element in the screenshot. By default, the element is highlighted with an orange border. Use any valid CSS styles to highlight the element.
     * To clear existing highlights, set the clear property to true.
     */
    highlight?: string | string[] | SelectableHighlightAction | (string | SelectableHighlightAction)[] | {
        clear: true;
    };
    /**
     * The screenshot action triggers a screenshot of the current state of the application.
     */
    screenshot?: string | (ScreenshotAction & Partial<Selectable>);
    /**
     * A scroll action scrolls the page to a specific position or element. Use the position property to scroll to a specific position or the element property to scroll to a selected DOM element.
     */
    scrollTo?: string | ScrollToAction | Selectable;
    /**
     * A text action modifies the text value of selected DOM element.
     */
    text?: TextAction & Selectable;
    /**
     * A type action triggers a type event on the selected DOM element. Use to simulate typing in an input field.
     */
    type?: TypeAction & Selectable;
    /**
     * A wait action waits for the given time in ms or for a given chainer assertion.
     * @examples [1000, 10000]
     */
    wait?: number | WaitAction;
}
type SelectorDataCyProperties = {
    "data-cy"?: string;
};
type SelectorLanguageProperties = {
    /**
     * The language(s) this selector is valid for. If the language of the application matches the language of the selector, the selector is used to select the element.
     * If language is not supported by the selector, the selector is ignored.
     * @examples ["en", "de", ["en", "de"]]
     */
    language?: string | string[];
};
type SelectorLocalizedProperties = {
    /**
     * Language key and localized selector mapping. Use for example to select elements based on the language of the application.
     * @examples [{ "de": "span.label-info:not(:contains('Objekt'))", "en": "span.label-info:not(:contains('Object'))" }]
     */
    localized?: {
        [key: string]: string;
    };
};
type SelectorProperties = SelectorDataCyProperties | SelectorLanguageProperties | SelectorLocalizedProperties;
type Selector = {
    /**
     * The selector to use to select the DOM element. The selector can be defined as string or an object with properties to select the element.
     */
    selector: string | SelectorProperties;
};
type Selectable = Selector | SelectorProperties;
type SharedSelector = {
    [key: string]: string;
};
interface C8yScreenshotFileUploadOptions {
    data: any;
    path: string;
    filename: string;
    encoding: string;
    mimeType?: string;
}

/**
 * Global type augmentations for Response and Cypress.Response interfaces.
 * This module extends the global interfaces to add custom properties used by c8yclient.
 */
declare global {
    interface Response {
        data?: string | any;
        method?: string;
        responseObj?: Partial<Cypress.Response<any>>;
        requestBody?: string | any;
    }
    namespace Cypress {
        interface Response<T> {
            url?: string;
            requestBody?: string | any;
            method?: string;
            $body?: any;
        }
    }
}

declare function readYamlFile(filePath: string): any;
declare function loadConfigFile(filePath: string, throws?: boolean): ScreenshotSetup | undefined;

/**
 * Configuration options for the Cumulocity Cypress plugin.
 */
type C8yPluginConfig = {
    /**
     * Folder where to store or load pact files from.
     * Default is cypress/fixtures/c8ypact
     */
    pactFolder?: string;
    /**
     * Adapter to load and save pact objects.
     * Default is C8yPactDefaultFileAdapter
     */
    pactAdapter?: C8yPactFileAdapter;
    /**
     * If enabled, all C8Y_* and C8YCTRL_* environment variables are passed to the
     * Cypress process. If C8Y_BASEURL or baseUrl env variables are configured,
     * the Cypress config baseUrl is overwritten. Default is true.
     */
    forwardEnvVariables?: boolean;
};
/**
 * Configuration options for the Cumulocity Pact plugin. Sets up for example required tasks
 * to save and load pact objects.
 *
 * @param on Cypress plugin events
 * @param config Cypress plugin config
 * @param options Cumulocity plugin configuration options
 */
declare function configureC8yPlugin(on: Cypress.PluginEvents, config: Cypress.PluginConfigOptions, options?: C8yPluginConfig): void;
/**
 * Configuration options for the Cumulocity Screenshot plugin and workflow. This sets up
 * the configuration as well as browser and screenshots handlers.
 * @param on Cypress plugin events
 * @param config Cypress plugin config
 * @param setup Configuration file or setup object
 */
declare function configureC8yScreenshotPlugin(on: Cypress.PluginEvents, config: Cypress.PluginConfigOptions, setup?: string | ScreenshotSetup): Cypress.PluginConfigOptions | undefined;
declare function appendCountIfPathExists(newPath: string): string;
declare function getFileUploadOptions(file: {
    path: string;
    fileName?: string;
    encoding?: BufferEncoding;
}, configFilePath: string | undefined, projectRoot: string): C8yScreenshotFileUploadOptions | null;
declare function resolvePactRefs(pact: any | string, baseFolder?: string, log?: (message: string) => void): Promise<any | null>;
declare function configureEnvVariables(config: Cypress.PluginConfigOptions, options?: {
    overwrite?: boolean;
    omit?: string[];
}): void;

export { C8yPactDefaultFileAdapter, C8yPactHARFileAdapter, appendCountIfPathExists, configureC8yPlugin, configureC8yScreenshotPlugin, configureEnvVariables, getFileUploadOptions, loadConfigFile, readYamlFile, resolvePactRefs };
export type { C8yPactFileAdapter, C8yPluginConfig };
