UNPKG

cumulocity-cypress

Version:
423 lines (422 loc) 15.4 kB
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;