cumulocity-cypress
Version:
Cypress commands for Cumulocity IoT
431 lines (421 loc) • 16.3 kB
TypeScript
import { IUser, Client, IApplication, IResult, IUserGroup, ICredentials, IAuthentication, FetchClient } from '@c8y/client';
/**
* Options for delete operations.
*/
type DeleteOptions = {
/**
* If true, ignores 404 Not Found errors when deleting.
*/
ignoreNotFound?: boolean;
};
/**
* Input types for deleteUser function.
*/
type DeleteUserInput = string | IUser | string[] | IUser[] | ((filter: IUser) => boolean);
/**
* Creates a user with the specified global roles and optionally assigns applications.
*
* This function:
* 1. Creates the user in Cumulocity
* 2. Assigns the user to the specified global role groups
* 3. Optionally assigns applications to the user (by name or IApplication object)
*
* @param client - The Cumulocity client instance
* @param user - The user object to create (must include userName, email, etc.)
* @param globalRoles - Array of global role names to assign to the user
* @param applications - Optional array of application names (strings) or IApplication objects to assign
* @returns Promise resolving to the created user result
*
* @throws Error if user creation fails or if roles/applications cannot be assigned
*
* @example
* const userResult = await createUser(
* client,
* { userName: 'john.doe', email: 'john@example.com', password: 'SecurePass123!' },
* ['business'],
* ['cockpit', 'devicemanagement']
* );
*/
declare function createUser(client: Client, user: IUser, globalRoles: string[], applications?: string[] | IApplication[]): Promise<IResult<IUser>>;
/**
* Deletes one or more users from Cumulocity.
*
* Supports multiple input formats:
* - Single username string
* - Single IUser object (matched by id, userName, displayName, self, or email)
* - Array of usernames or IUser objects
* - Filter function to select users to delete
*
* When an IUser object is provided, the function matches it against existing users using
* any available identifying properties (id, userName, displayName, self, email). This allows
* for flexible matching even with partial user objects.
*
* @param client - The Cumulocity client instance
* @param user - Username(s), IUser object(s), or filter function to identify users to delete
* @param options - Optional configuration
* @param options.ignoreNotFound - If true (default), ignores 404 errors when user is not found
* @returns Promise that resolves when all users are deleted
*
* @throws Error if user is missing required properties or if deletion fails (unless ignoreNotFound is true)
*
* @example
* // Delete single user by username
* await deleteUser(client, 'john.doe');
*
* @example
* // Delete multiple users
* await deleteUser(client, ['user1', 'user2', 'user3']);
*
* @example
* // Delete users matching a filter
* await deleteUser(client, (user) => user.email?.includes('@example.com'));
*
* @example
* // Delete user by partial IUser object
* await deleteUser(client, { displayName: 'John Doe', email: 'john@example.com' });
*/
declare function deleteUser(client: Client, user: DeleteUserInput, options?: DeleteOptions): Promise<void>;
/**
* Assigns one or more global roles to a user.
*
* This function adds the user to the specified global role groups, granting them
* the permissions associated with those roles.
*
* @param client - The Cumulocity client instance
* @param username - Username string or IUser object (must have userName property)
* @param roles - Array of global role names to assign to the user
* @returns Promise that resolves when all roles are assigned
*
* @throws Error if username is missing, roles array is empty, or if role assignment fails
*
* @example
* await assignUserRoles(client, 'john.doe', ['business', 'admins']);
*
* @example
* const user = await client.user.detail('john.doe');
* await assignUserRoles(client, user.data, ['devicemanagement']);
*/
declare function assignUserRoles(client: Client, username: string | IUser, roles: string[]): Promise<void>;
/**
* Removes all global roles currently assigned to a user.
*
* This function removes the user from all global role groups, effectively
* revoking all role-based permissions.
*
* @param client - The Cumulocity client instance
* @param username - Username string or IUser object (must have userName property)
* @returns Promise that resolves when all roles are removed
*
* @throws Error if username is missing or if role removal fails
*
* @example
* await clearUserRoles(client, 'john.doe');
*
* @example
* const user = await client.user.detail('john.doe');
* await clearUserRoles(client, user.data);
*/
declare function clearUserRoles(client: Client, username: string | IUser): Promise<void>;
/**
* Generates a secure random password with mixed case letters, numbers, and special characters.
*
* The password includes:
* - Uppercase and lowercase letters (50% chance for each letter)
* - Numbers (from timestamp)
* - Special characters (!@#$%^&*())
*
* @param length - The desired length of the password (default: 28, minimum: 8)
* @returns A randomly generated password string
*
* @example
* const password = generatePassword();
* // Returns something like: "2Kl9j8Gh!4m2@x7n#5p3q8r9"
*
* @example
* const shortPassword = generatePassword(12);
* // Returns a 12-character password
*/
declare function generatePassword(length?: number): string;
/**
* Creates a global role (user group) with the specified permissions.
*
* Global roles are user groups that define a set of permissions. This function:
* 1. Creates a new user group with the specified name
* 2. Assigns the specified role permissions to the group
*
* @param client - The Cumulocity client instance
* @param roleOptions - Role name as string, or object with name and optional description
* @param permissions - Array of permission (role) IDs or names to assign to this global role (e.g., ['ROLE_USER_MANAGEMENT', 'ROLE_INVENTORY_READ'])
* @returns Promise resolving to the created user group result
*
* @throws Error if role creation fails or if any of the specified roles cannot be found
*
* @example
* const roleResult = await createGlobalRole(
* client,
* { name: 'Custom Admin', description: 'Custom admin role with specific permissions' },
* ['ROLE_USER_MANAGEMENT', 'ROLE_INVENTORY_ADMIN']
* );
*/
declare function createGlobalRole(client: Client, roleOptions: string | {
name: string;
description?: string;
}, permissions: string[]): Promise<IResult<IUserGroup>>;
/**
* Deletes one or more global roles (user groups) by name.
*
* @param client - The Cumulocity client instance
* @param roleNames - Single role name or array of role names to delete
* @param options - Optional configuration
* @param options.ignoreNotFound - If true (default), ignores 404 errors when role is not found
* @returns Promise that resolves when all roles are deleted
*
* @throws Error if role names are missing or if deletion fails (unless ignoreNotFound is true)
*
* @example
* // Delete single role
* await deleteGlobalRoles(client, 'CustomRole');
*
* @example
* // Delete multiple roles
* await deleteGlobalRoles(client, ['Role1', 'Role2', 'Role3']);
*/
declare function deleteGlobalRoles(client: Client, roleNames: string | string[], options?: DeleteOptions): Promise<void>;
/**
* 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 C8yAuthOptions extends ICredentials {
sendImmediately?: boolean;
userAlias?: string;
type?: string;
xsrfToken?: string;
}
type C8yPactAuthObject = {
user: string;
userAlias?: string;
type?: string;
token?: string;
} | {
userAlias: string;
user?: string;
type?: string;
token?: string;
};
type C8yPactAuthObjectType = keyof C8yPactAuthObject;
declare const C8yPactAuthObjectKeys: C8yPactAuthObjectType[];
type C8yAuthOptionType = "BasicAuth" | "CookieAuth" | "BearerAuth" | undefined;
type C8yAuthentication = IAuthentication;
/**
* Checks if the given object is a C8yAuthOptions.
*
* @param obj The object to check.
* @param options Options to check for additional properties.
* @returns True if the object is a C8yAuthOptions, false otherwise.
*/
declare function isAuthOptions(obj: any): obj is C8yAuthOptions;
declare function toC8yAuthentication(obj: C8yAuthOptions | IAuthentication | undefined): C8yAuthentication | undefined;
declare function getAuthType(auth?: C8yAuthOptions | C8yPactAuthObject | string): C8yAuthOptionType;
declare function hasAuthentication(client: C8yClient | Client | FetchClient): boolean;
declare function toPactAuthObject(obj: C8yAuthOptions | IAuthentication | ICredentials): C8yPactAuthObject;
declare function isPactAuthObject(obj: any): obj is C8yPactAuthObject;
declare function normalizeAuthHeaders(headers: {
[key: string]: any;
}): {
[key: string]: any;
};
declare function getAuthOptionsFromEnv(env: any): C8yAuthOptions | undefined;
declare function authWithTenant(env: any, options: C8yAuthOptions): C8yAuthOptions;
declare function getAuthOptionsFromBasicAuthHeader(authHeader: string): {
user: string;
password: string;
} | undefined;
/**
* Extracts the authentication options from a JWT token.
* @param jwtToken The JWT token to extract the authentication options from.
* @returns The extracted authentication options.
*/
declare function getAuthOptionsFromJWT(jwtToken: string): C8yAuthOptions;
/**
* Extracts the tenant from the basic auth object.
* @param auth The basic auth object containing the user property.
* @returns The tenant or undefined if not found.
*/
declare function tenantFromBasicAuth(auth: {
user?: string | undefined;
} | string): string | undefined;
declare function encodeBase64(str: string): string;
declare function decodeBase64(base64: string): 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;
}
/**
* 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;
}>;
/**
* Wrapper for Client to pass auth and options without extending Client.
* Using underscore to avoid name clashes with Client and misunderstandings reading the code.
*/
interface C8yClient {
_auth?: C8yAuthentication;
_options?: C8yClientOptions;
_client?: Client;
}
/**
* ID representing a pact object. Should be unique.
* @example api__get__permission_failure_tests
*/
type C8yPactID = string;
/**
* 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;
}
declare function isURL(obj: any): obj is URL;
declare function relativeURL(url: URL | string): string | undefined;
declare function urlForBaseUrl(baseUrl: string, relativeOrAbsoluteUrl?: string): string | undefined;
declare function removeBaseUrlFromString(url: string, baseUrl?: C8yBaseUrl): string;
declare function removeBaseUrlFromRequestUrl(record: C8yPactRecord, baseUrl?: C8yBaseUrl): void;
declare function normalizeUrl(url: string): string;
declare function tenantUrl(baseUrl?: C8yBaseUrl, tenant?: C8yTenant): string | undefined;
declare function updateURLs(value: string, from: {
baseUrl: C8yBaseUrl;
tenant?: C8yTenant;
}, to: {
baseUrl: C8yBaseUrl;
tenant?: C8yTenant;
}): string;
/**
* Checks if the given URL is an absolute URL.
* @param url The URL to check.
* @returns True if the URL is an absolute URL, false otherwise.
*/
declare function isAbsoluteURL(url: string): boolean;
/**
* Validates the base URL and throws an error if the base URL is not an absolute URL. This
* is required as commands expect an absolute URL as baseUrl. Will not fail for undefined values.
* `Cypress.config().baseUrl` is validated by Cypress itself and throw an error.
*
* @param baseUrl The url to validate.
*/
declare function validateBaseUrl(baseUrl?: C8yBaseUrl): void;
/**
* Normalizes a URL to ensure it has a protocol and proper trailing slash.
* If no protocol is present, HTTPS is added by default.
* If the URL has no path component, a trailing slash is appended.
*
* @param url - The URL string to normalize
* @returns The normalized URL with HTTPS protocol and trailing slash if appropriate, or undefined for invalid input
*/
declare function normalizeBaseUrl(url: string | undefined): string | undefined;
/**
* Converts the given URL to a string.
* @param url The URL or RequestInfo to convert.
* @returns The URL as a string.
*/
declare function toUrlString(url: RequestInfo | URL): string;
export { C8yPactAuthObjectKeys, assignUserRoles, authWithTenant, clearUserRoles, createGlobalRole, createUser, decodeBase64, deleteGlobalRoles, deleteUser, encodeBase64, generatePassword, getAuthOptionsFromBasicAuthHeader, getAuthOptionsFromEnv, getAuthOptionsFromJWT, getAuthType, hasAuthentication, isAbsoluteURL, isAuthOptions, isPactAuthObject, isURL, normalizeAuthHeaders, normalizeBaseUrl, normalizeUrl, relativeURL, removeBaseUrlFromRequestUrl, removeBaseUrlFromString, tenantFromBasicAuth, tenantUrl, toC8yAuthentication, toPactAuthObject, toUrlString, updateURLs, urlForBaseUrl, validateBaseUrl };
export type { C8yAuthOptionType, C8yAuthOptions, C8yAuthentication, C8yPactAuthObject, DeleteOptions, DeleteUserInput };