From 226f4de1aef5b23b7ab406b073ecda9d3bfa4002 Mon Sep 17 00:00:00 2001 From: Roman Kuznetsov Date: Thu, 9 Apr 2026 01:45:55 +0300 Subject: [PATCH] feat: add ability to use custom wd request agent --- packages/wdio-types/src/Capabilities.ts | 9 ++++++++ packages/wdio-types/src/Options.ts | 29 ++++++++++++++++++++++--- packages/webdriver/src/constants.ts | 6 +++++ packages/webdriver/src/request/index.ts | 10 +++++---- packages/webdriver/src/request/node.ts | 4 ++-- packages/webdriver/src/request/web.ts | 4 ++-- packages/webdriver/src/types.ts | 2 ++ packages/webdriver/src/utils.ts | 1 - 8 files changed, 53 insertions(+), 12 deletions(-) diff --git a/packages/wdio-types/src/Capabilities.ts b/packages/wdio-types/src/Capabilities.ts index 9727cfd1c59..d6914df0002 100644 --- a/packages/wdio-types/src/Capabilities.ts +++ b/packages/wdio-types/src/Capabilities.ts @@ -381,6 +381,15 @@ export interface VendorExtensions extends EdgeCapabilities, AppiumCapabilities, * Selenium 4.0 Specific */ 'se:cdp'?: string + + /** + * Selenoid custom + */ + 'se:wsdriver'?: string + /** + * Selenoid custom + */ + 'se:wsdriverVersion'?: string } export type AppiumOptions = RemoveAppiumPrefix diff --git a/packages/wdio-types/src/Options.ts b/packages/wdio-types/src/Options.ts index c9b79135fde..4daffd53084 100644 --- a/packages/wdio-types/src/Options.ts +++ b/packages/wdio-types/src/Options.ts @@ -31,9 +31,28 @@ export interface RequestLibOptions { } export interface RequestLibResponse { - statusCode: number - body?: Body - rawBody?: Buffer + url: string; + method: string; + statusCode: number; + statusMessage: string; + req: { + method: string; + path: string; + host: string; + res: RequestLibResponse; + }, + request: { + options: RequestLibOptions; + requestUrl: URL; + response: RequestLibResponse; + }; + ok: boolean; + body?: Body; + rawBody?: Buffer; +} + +export interface CustomWdRequestAgent { + request: (url: globalThis.URL, options: Omit) => Promise } export interface ShardOptions { @@ -180,6 +199,10 @@ export interface WebDriver extends Connection { * when attempting to start a session. */ cacheDir?: string + /** + * Custom webdriver request agent + */ + customWdRequestAgent?: CustomWdRequestAgent } export type SauceRegions = 'us' | 'eu' | 'us-west-1' | 'us-east-4' | 'eu-central-1' | 'staging' diff --git a/packages/webdriver/src/constants.ts b/packages/webdriver/src/constants.ts index a3d845591ff..bfc92f71538 100644 --- a/packages/webdriver/src/constants.ts +++ b/packages/webdriver/src/constants.ts @@ -147,6 +147,12 @@ export const DEFAULTS: Options.Definition> = { cacheDir: { type: 'string', default: environment.value.variables.WEBDRIVER_CACHE_DIR + }, + /** + * Custom webdriver request agent + */ + customWdRequestAgent: { + type: 'object', } } diff --git a/packages/webdriver/src/request/index.ts b/packages/webdriver/src/request/index.ts index 9d9ed171f41..cb3f19463dd 100644 --- a/packages/webdriver/src/request/index.ts +++ b/packages/webdriver/src/request/index.ts @@ -75,7 +75,7 @@ export default abstract class WebDriverRequest extends EventEmitter { } this.emit('request', fullRequestOptions) - return this._request(fullRequestOptions, options.transformResponse, options.connectionRetryCount, 0) + return this._request(fullRequestOptions, options.transformResponse, options.customWdRequestAgent, options.connectionRetryCount, 0) } protected async _createOptions (options: RequestOptions, sessionId?: string, isBrowser: boolean = false): Promise { @@ -167,6 +167,7 @@ export default abstract class WebDriverRequest extends EventEmitter { private async _request ( fullRequestOptions: RequestLibOptions, transformResponse?: (response: RequestLibResponse, requestOptions: RequestLibOptions) => RequestLibResponse, + customWdRequestAgent: Options.CustomWdRequestAgent | null = null, totalRetryCount = 0, retryCount = 0 ): Promise { @@ -178,8 +179,9 @@ export default abstract class WebDriverRequest extends EventEmitter { const { url, retry: _, ...requestLibOptions } = fullRequestOptions const startTime = this._libPerformanceNow() - let response = await this._libRequest(url!, requestLibOptions) - .catch((err: RequestLibError) => err) + let response = customWdRequestAgent + ? await customWdRequestAgent.request(url!, requestLibOptions).catch((err: RequestLibError) => err) + : await this._libRequest(url!, requestLibOptions).catch((err: RequestLibError) => err) const durationMillisecond = this._libPerformanceNow() - startTime /** @@ -204,7 +206,7 @@ export default abstract class WebDriverRequest extends EventEmitter { this.emit('performance', { request: fullRequestOptions, durationMillisecond, success: false, error, retryCount }) log.warn(msg) log.info(`Retrying ${retryCount}/${totalRetryCount}`) - return this._request(fullRequestOptions, transformResponse, totalRetryCount, retryCount) + return this._request(fullRequestOptions, transformResponse, customWdRequestAgent, totalRetryCount, retryCount) } /** diff --git a/packages/webdriver/src/request/node.ts b/packages/webdriver/src/request/node.ts index a8b6120a84c..d7d6a99b001 100644 --- a/packages/webdriver/src/request/node.ts +++ b/packages/webdriver/src/request/node.ts @@ -4,7 +4,7 @@ import https from 'node:https' import { performance } from 'node:perf_hooks' import type { URL } from 'node:url' -import got, { type OptionsOfTextResponseBody } from 'got' +import got, { type OptionsOfJSONResponseBody } from 'got' import type { Options } from '@testplane/wdio-types' import WebDriverRequest, { RequestLibError } from './index.js' @@ -26,7 +26,7 @@ export class NodeJSRequest extends WebDriverRequest { protected async _libRequest (url: URL, opts: Options.RequestLibOptions) { try { - return (await got(url, opts as OptionsOfTextResponseBody)) as Options.RequestLibResponse + return (await got(url, opts as OptionsOfJSONResponseBody)) as unknown as Options.RequestLibResponse // eslint-disable-next-line @typescript-eslint/no-explicit-any } catch (err: any) { if (!(err instanceof Error)) { diff --git a/packages/webdriver/src/request/web.ts b/packages/webdriver/src/request/web.ts index 1d7867f5233..b8e38cfb4eb 100644 --- a/packages/webdriver/src/request/web.ts +++ b/packages/webdriver/src/request/web.ts @@ -2,7 +2,7 @@ import type { Options as KyOptions } from 'ky' import ky from 'ky' import logger from '@testplane/wdio-logger' import WebDriverRequest from './index.js' -import type { RequestOptions, RequestLibOptions } from './types.js' +import type { RequestOptions, RequestLibOptions, RequestLibResponse } from './types.js' const log = logger('webdriver') @@ -49,7 +49,7 @@ export class WebRequest extends WebDriverRequest { return { statusCode: res.status, body: await res.json(), - } + } as RequestLibResponse } protected _libPerformanceNow(): number { diff --git a/packages/webdriver/src/types.ts b/packages/webdriver/src/types.ts index 96a4b71bf76..1db987cff60 100644 --- a/packages/webdriver/src/types.ts +++ b/packages/webdriver/src/types.ts @@ -94,4 +94,6 @@ export interface AttachOptions extends Partial, Partial