electron-playwright-helpers
Version:
Helper functions for Electron end-to-end testing using Playwright
178 lines • 8.85 kB
TypeScript
import * as helpers from './';
export type AllHelpers = typeof helpers;
export type AllPromiseHelpers = {
[K in keyof AllHelpers]: ReturnType<AllHelpers[K]> extends Promise<unknown> ? AllHelpers[K] : never;
};
export type AllPromiseHelpersWithoutTimeout = Omit<AllPromiseHelpers, 'addTimeoutToPromise' | 'addTimeout'>;
export type HelperFunctionName = keyof AllPromiseHelpersWithoutTimeout;
/**
* Add a timeout to any Promise
*
* @category Utilities
* @see addTimeout
*
* @param promise - the promise to add a timeout to - must be a Promise
* @param timeoutMs - the timeout in milliseconds - defaults to 5000
* @param timeoutMessage - optional - the message to return if the timeout is reached
*
* @returns {Promise<T>} the result of the original promise if it resolves before the timeout
*/
export declare function addTimeoutToPromise<T>(promise: Promise<T>, timeoutMs?: number, timeoutMessage?: string): Promise<T>;
/**
* Add a timeout to any helper function from this library which returns a Promise.
*
* @category Utilities
*
* @param functionName - the name of the helper function to call
* @param timeoutMs - the timeout in milliseconds - defaults to 5000
* @param timeoutMessage - optional - the message to return if the timeout is reached
* @param args - any arguments to pass to the helper function
*
* @returns {Promise<T>} the result of the helper function if it resolves before the timeout
*/
export declare function addTimeout<T extends HelperFunctionName>(functionName: T, timeoutMs?: number, timeoutMessage?: string, ...args: Parameters<AllPromiseHelpers[T]>): ReturnType<AllPromiseHelpers[T]>;
export type RetryOptions = {
/** The maximum time to wait before giving up (in milliseconds) */
timeout: number;
/** The delay between each retry attempt in milliseconds. Or use "raf" for requestAnimationFrame. */
poll: number | 'raf';
/**
* The error message or pattern to match against. Errors that don't match will throw immediately.
* If a string or array of strings, the error will throw if it does not contain (one of) the passed string(s).
* If a RegExp, the error will throw if it does not match the pattern.
*/
errorMatch: string | string[] | RegExp;
/** If true, the retry function will be disabled and will throw immediately. */
disable: boolean;
};
/**
* Retries a function until it returns without throwing an error.
*
* Starting with Electron 27, Playwright can get very flakey when running code in Electron's main or renderer processes.
* It will often throw errors like "context or browser has been closed" or "Promise was collected" for no apparent reason.
* This function retries a given function until it returns without throwing one of these errors, or until the timeout is reached.
*
*
* @example
*
* You can simply wrap your Playwright calls in this function to make them more reliable:
*
* ```javascript
* test('my test', async () => {
* // instead of this:
* const oldWayRenderer = await page.evaluate(() => document.body.classList.contains('active'))
* const oldWayMain = await electronApp.evaluate(({}) => document.body.classList.contains('active'))
* // use this:
* const newWay = await retry(() =>
* page.evaluate(() => document.body.classList.contains('active'))
* )
* // note the `() =>` in front of the original function call
* // and the `await` keyword in front of `retry`,
* // but NOT in front of `page.evaluate`
* })
* ```
*
* @category Utilities
*
* @template T The type of the value returned by the function.
* @param {Function} fn The function to retry.
* @param {RetryOptions} [options={}] The options for retrying the function.
* @param {number} [options.timeout=5000] The maximum time to wait before giving up in milliseconds.
* @param {number} [options.poll=200] The delay between each retry attempt in milliseconds.
* @param {string|string[]|RegExp} [options.errorMatch=['context or browser has been closed', 'Promise was collected', 'Execution context was destroyed']] String(s) or regex to match against error message. If the error does not match, it will throw immediately. If it does match, it will retry.
* @returns {Promise<T>} A promise that resolves with the result of the function or rejects with an error or timeout message.
*/
export declare function retry<T>(fn: () => Promise<T> | T, options?: Partial<RetryOptions>): Promise<T>;
/**
* Sets the default retry() options. These options will be used for all subsequent calls to retry() unless overridden.
* You can reset the defaults at any time by calling resetRetryOptions().
*
* @category Utilities
*
* @param options - A partial object containing the retry options to be set.
* @returns The updated retry options.
*/
export declare function setRetryOptions(options: Partial<RetryOptions>): RetryOptions;
/**
* Gets the current default retry options.
*
* @category Utilities
*
* @returns The current retry options.
*/
export declare function getRetryOptions(): RetryOptions;
/**
* Resets the retry options to their default values.
*
* The default values are:
* - retries: 20
* - intervalMs: 200
* - timeoutMs: 5000
* - errorMatch: 'context or browser has been closed'
*
* @category Utilities
*/
export declare function resetRetryOptions(): void;
export declare function isRetryOptions(options: unknown): options is RetryOptions;
export type RetryUntilTruthyOptions = {
/** The maximum time (milliseconds) to wait for a truthy result. Default 5000. */
timeout: number;
/** The interval (milliseconds) between each retry (after a falsy result) */
poll: number | 'raf';
/** The maximum amount of time (milliseconds) to wait for an individual try to return a result */
retryTimeout: number;
/** The amount of time (milliseconds) to wait before retrying after an error */
retryPoll: number;
/** The error message or pattern to match against. Errors that don't match will throw immediately. */
retryErrorMatch: string | string[] | RegExp;
/** If true, the retry function will be disabled and will throw immediately. */
retryDisable: boolean;
};
/**
* Retries a given function until it returns a truthy value or the timeout is reached.
*
* This offers similar functionality to Playwright's [`page.waitForFunction()`](https://playwright.dev/docs/api/class-page#page-wait-for-function)
* method – but with more flexibility and control over the retry attempts. It also defaults to ignoring common errors due to
* the way that Playwright handles browser contexts.
*
* @example
*
* ```javascript
* test('my test', async () => {
* // this will fail immediately if Playwright's context gets weird:
* const oldWay = await page.waitForFunction(() => document.body.classList.contains('ready'))
*
* // this will not fail if Playwright's context gets weird:
* const newWay = await retryUntilTruthy(() =>
* page.evaluate(() => document.body.classList.contains('ready'))
* )
* })
* ```
*
* @template T - The type of the value returned by the function.
* @param {Function} fn - The function to retry. It can return a promise or a value. It should NOT return void/undefined.
* @param {number} [timeoutMs=5000] - The maximum time in milliseconds to keep retrying the function. Defaults to 5000ms.
* @param {number} [intervalMs=100] - The delay between each retry attempt in milliseconds. Defaults to 100ms.
* @param {number} [options.retryTimeout=5000] - The maximum time in milliseconds to wait for an individual try to return a result. Defaults to 5000ms.
* @param {number} [options.retryPoll=200] - The delay between each retry attempt in milliseconds. Defaults to 200ms.
* @param {string|string[]|RegExp} [options.retryErrorMatch] - The error message or pattern to match against. Errors that don't match will throw immediately.
* @returns {Promise<T>} - A promise that resolves to the truthy value returned by the function.
* @throws {Error} - Throws an error if the timeout is reached before a truthy value is returned.
*/
export declare function retryUntilTruthy<T>(fn: () => Promise<T> | T, options?: Partial<RetryUntilTruthyOptions>): Promise<T>;
/**
* Converts an unknown error to a string representation.
*
* This function handles different types of errors and attempts to convert them
* to a string in a meaningful way. It checks if the error is an object with a
* `toString` method and uses that method if available. If the error is a string,
* it returns the string directly. For other types, it converts the error to a
* JSON string.
*
* @category Utilities
*
* @param err - The unknown error to be converted to a string.
* @returns A string representation of the error.
*/
export declare function errToString(err: unknown): string;
//# sourceMappingURL=utilities.d.ts.map