cumulocity-cypress
Version:
Cypress commands for Cumulocity IoT
423 lines (422 loc) • 15.4 kB
TypeScript
import { C8yPactPreprocessorOptions } from "./preprocessor";
import { C8yClientOptions } from "../c8yclient";
import { C8yPactAuthObject } from "../auth";
import { C8yBaseUrl, C8yTenant } from "../types";
export declare const C8yPactModeValues: readonly ["record", "recording", "apply", "forward", "disabled", "mock"];
/**
* The pact mode is used to determine the behavior of the recording and mocking capabilities.
* - `record`: Records the requests and responses and stores them in a pact file.
* - `apply`: Mocks or matches the requests and responses from the recorded pact file.
* - `disabled`: Disables the pact recording and mocking (same as undefined).
* - `forward`: Forward requests without recording or mocking (might not be supported in all contexts).
* - `recording` (deprecated): same as `record`, use `record` instead.
* - `mock`: Mock responses for requests. Same as `apply`, but `apply` could also mean matching the requests and responses depending on the context.
*/
export type C8yPactMode = (typeof C8yPactModeValues)[number];
export 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.
*/
export type C8yPactRecordingMode = (typeof C8yPactRecordingModeValues)[number];
/**
* ID representing a pact object. Should be unique.
* @example api__get__permission_failure_tests
*/
export type C8yPactID = string;
export interface C8yPactRequestMatchingOptions {
ignoreUrlParameters?: string[];
baseUrl?: C8yBaseUrl;
}
export 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;
}
export type C8yPactConfigKeys = keyof C8yPactConfigOptions;
export interface C8yPactEnv {
tenant?: C8yTenant;
loggedInUser?: string;
loggedInUserAlias?: string;
testTitlePath?: string[];
systemVersion?: string;
pluginVersion?: string;
pluginFolder?: string;
}
export 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;
}
export declare const C8yPactObjectKeys: string[];
/**
* 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.
*/
export 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>;
}
export interface C8yPactInfoVersion {
system?: string;
c8ypact?: string;
runner?: string;
}
/**
* Meta information describing a pact and how it was recorded.
*/
export 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.
*/
export type C8yPactRequest = Partial<Cypress.RequestOptions> & {
$body?: any;
};
/**
* The response stored in a C8yPactRecord.
*/
export 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.
*/
export 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;
}
export declare function isValidPactId(value: string): boolean;
/**
* Creates an C8yPactID for a given string or array of strings.
* @param value The string or array of strings to convert to a pact id.
* @returns The pact id.
*/
export declare function pactId(value: string | string[]): C8yPactID | undefined;
/**
* Validate the given pact mode. Throws an error if the mode is not supported
* or undefined.
* @param mode The pact mode to validate.
*/
export declare function validatePactMode(mode?: string): void;
/**
* Validate the given pact recording mode. Throws an error if the mode is not supported
* or undefined.
* @param mode The pact recording mode to validate.
*/
export declare function validatePactRecordingMode(mode?: string): void;
/**
* Checks if the given object is a C8yPact. This also includes checking
* all records to be valid C8yPactRecord instances.
*
* @param obj The object to check.
* @returns True if the object is a C8yPact, false otherwise.
*/
export declare function isPact(obj: any): obj is C8yPact;
/**
* Checks if the given object is a C8yPactRecord.
*
* @param obj The object to check.
* @returns True if the object is a C8yPactRecord, false otherwise.
*/
export declare function isPactRecord(obj: any): obj is C8yPactRecord;
/**
* Checks if the given object is a Cypress.Response.
*
* @param obj The object to check.
* @returns True if the object is a Cypress.Response, false otherwise.
*/
export declare function isCypressResponse(obj: any): obj is Cypress.Response<any>;
/**
* Checks if the given object is a C8yPactError. A C8yPactError is an error
* with the name "C8yPactError".
*
* @param error The object to check.
* @returns True if the object is a C8yPactError, false otherwise.
*/
export declare function isPactError(error: any): boolean;
/**
* Converts a Cypress.Response to a C8yPactRequest.
*/
export declare function toPactRequest(response: Cypress.Response<any> | Partial<Cypress.Response<any>>): C8yPactRequest | undefined;
/**
* Converts a Cypress.Response to a C8yPactResponse.
*/
export declare function toPactResponse<T>(response: Cypress.Response<T> | Partial<Cypress.Response<T>>): C8yPactResponse<T> | undefined;
export type C8yPactSaveKeys = "id" | "info" | "records";
/**
* Returns the value of the environment variable with the given name. The function
* tries to find the value in the global `process.env` or `Cypress.env()`. If `env`
* is provided, the function uses the given object as environment.
*
* The function tries to find the value in the following order:
* - `name`
* - `camelCase(name)`
* - `CYPRESS_name`
* - `name.replace(/^C8Y_/i, "")`
* - `CYPRESS_camelCase(name)`
* - `CYPRESS_camelCase(name.replace(/^C8Y_/i, ""))`
*
* @param name The name of the environment variable.
* @param env The environment object to use. Default is `process.env` or `Cypress.env()`
*
* @returns The value of the environment variable or `undefined` if not found.
*/
export declare function getEnvVar(name: string, env?: {
[key: string]: string;
}): string | undefined;
export declare function isOneOfStrings(value: string, values: string[]): boolean;
export declare function getCreatedObjectId(response: Cypress.Response<any> | Partial<Cypress.Response<any>> | C8yPactResponse<any>): string | undefined;