chore: replace safe occurrences of JWProxy (#22614)

This commit is contained in:
Edgars Eglītis
2026-08-06 16:54:45 +03:00
committed by GitHub
parent 01a4eaec49
commit 1486078c82
8 changed files with 53 additions and 54 deletions
@@ -525,14 +525,13 @@ route, then the route will not be proxied and instead will be handled by your dr
example, we are avoiding proxying all `POST` routes that have the `appium` prefix.
Next, we have to set up the proxying itself. The way to do this is to use a special class from
Appium called `JWProxy`. (The name means "JSON Wire Proxy" and is related to a legacy
implementation of the protocol). You'll want to create a `JWProxy` object using the details required to
connect to the remote server:
Appium called `WebDriverProxy`. You'll want to create a `WebDriverProxy` object using the details
required to connect to the remote server:
```js
// import {JWProxy} from 'appium/driver';
// import {WebDriverProxy} from 'appium/driver';
const proxy = new JWProxy({
const proxy = new WebDriverProxy({
server: 'remote.server',
port: 1234,
base: '/',
@@ -544,8 +543,8 @@ this.proxyCommand = proxy.command.bind(proxy);
Here we are creating a proxy object and assigning some of its methods to `this` under the names
`proxyReqRes` and `proxyCommand`. This is required for Appium to use the proxy, so don't forget
this step! The `JWProxy` has a variety of other options which you can check out in the source code,
as well. (TODO: publish options as API docs and link here).
this step! The `WebDriverProxy` has a variety of other options [which you can check out in the
source code as well.](https://github.com/appium/appium/blob/master/packages/base-driver/lib/jsonwp-proxy/proxy.ts)
Finally, we need a way to tell Appium when the proxy is active. For your driver it might always
be active, or it might only be active when in a certain context. You can define the logic as an
@@ -283,7 +283,7 @@ export function routeConfiguringFunction(driver: Core<any>): RouteConfiguringFun
}
/**
* Whether an incoming request should be forwarded to the driver's JWProxy for the given command.
* Whether an incoming request should be forwarded to the driver's WebDriverProxy for the given command.
* @param driver - Active driver
* @param req - Incoming HTTP request
* @param command - Resolved driver command name
@@ -422,7 +422,7 @@ function buildHandler(
typeof driver.pluginsToHandleCmd !== 'function' ||
driver.pluginsToHandleCmd(spec.command, sessionId).length === 0
) {
await doJwpProxy(driver as BaseDriver<any>, req, res);
await doWdProxy(driver as BaseDriver<any>, req, res);
return;
}
getLogger(driver, sessionId).debug(
@@ -602,7 +602,7 @@ function buildHandler(
});
}
async function doJwpProxy(driver: BaseDriver<any>, req: Request, res: Response): Promise<void> {
async function doWdProxy(driver: BaseDriver<any>, req: Request, res: Response): Promise<void> {
const sessionId = getSessionId(driver, req) as string;
getLogger(driver, sessionId).info('Driver proxy active, passing request on via HTTP proxy');
@@ -3,19 +3,19 @@ import {after, afterEach, before, describe, it} from 'node:test';
import {TEST_HOST} from '@appium/driver-test-support';
import {JWProxy} from '../../../lib';
import {WebDriverProxy} from '../../../lib';
import {createServer} from '../../helpers';
import {FakeDriver} from '../protocol/fake-driver';
describe('proxy', function () {
let jwproxy: JWProxy;
let wdproxy: WebDriverProxy;
let teardown: () => Promise<void> | undefined;
before(async function () {
const {port, setup, teardown: teardownFn} = await createServer(new FakeDriver());
teardown = teardownFn;
await setup();
jwproxy = new JWProxy({server: TEST_HOST, port});
wdproxy = new WebDriverProxy({server: TEST_HOST, port});
});
after(async function () {
@@ -23,33 +23,33 @@ describe('proxy', function () {
});
it('should proxy status straight', async function () {
const [res, resBody] = await jwproxy.proxy('/status', 'GET');
const [res, resBody] = await wdproxy.proxy('/status', 'GET');
assert.strictEqual(res.statusCode, 200);
assert.strictEqual(resBody.value, `I'm fine`);
});
it('should proxy status as command', async function () {
const res = await jwproxy.command('/status', 'GET');
const res = await wdproxy.command('/status', 'GET');
assert.strictEqual(res, `I'm fine`);
});
describe('new session', function () {
afterEach(async function () {
await jwproxy.command('', 'DELETE');
await wdproxy.command('', 'DELETE');
});
it('should start a new session', async function () {
const caps = {browserName: 'fake'};
const res = await jwproxy.command('/session', 'POST', {
const res = await wdproxy.command('/session', 'POST', {
capabilities: {alwaysMatch: caps},
});
assert.ok(Object.hasOwn(res.capabilities.alwaysMatch, 'browserName'));
assert.strictEqual(jwproxy.sessionId!.length, 48);
assert.strictEqual(wdproxy.sessionId!.length, 48);
});
});
describe('delete session', function () {
it('should quit a session', async function () {
await jwproxy.command('/session', 'POST', {
await wdproxy.command('/session', 'POST', {
capabilities: {alwaysMatch: {browserName: 'fake'}},
});
const res = await jwproxy.command('', 'DELETE');
const res = await wdproxy.command('', 'DELETE');
assert.ok(!res);
});
});
@@ -19,13 +19,13 @@ class FakeDriver extends BaseDriver<Constraints> {
},
};
declare jwpProxyActive: boolean;
declare wdProxyActive: boolean;
constructor() {
super({} as InitialOpts);
this.protocol = PROTOCOLS.MJSONWP;
this.sessionId = null;
this.jwpProxyActive = false;
this.wdProxyActive = false;
}
sessionExists(sessionId?: string | null): boolean {
@@ -65,7 +65,7 @@ class FakeDriver extends BaseDriver<Constraints> {
}
async deleteSession(): Promise<void> {
this.jwpProxyActive = false;
this.wdProxyActive = false;
this.sessionId = null;
}
@@ -10,13 +10,13 @@ class MockExecuteDriver extends BaseDriver<Constraints> {
},
};
declare jwpProxyActive: boolean;
declare wdProxyActive: boolean;
constructor() {
super({} as InitialOpts);
this.protocol = PROTOCOLS.W3C;
this.sessionId = null;
this.jwpProxyActive = false;
this.wdProxyActive = false;
}
async execute(script: string, args: unknown[]): Promise<{executed: string; args: unknown[]}> {
@@ -8,7 +8,7 @@ import type {Application, Request, Response} from 'express';
import {StatusCodes as HTTPStatusCodes} from 'http-status-codes';
import {createSandbox} from 'sinon';
import {errors, JWProxy} from '../../../lib';
import {errors, WebDriverProxy} from '../../../lib';
import {MJSONWP_ELEMENT_KEY, W3C_ELEMENT_KEY} from '../../../lib/constants';
import {createServer} from '../../helpers';
import {FakeDriver} from './fake-driver';
@@ -460,10 +460,10 @@ describe('Protocol', function () {
delete (driver as any).performActions;
});
describe('jwproxy', function () {
describe('wdproxy', function () {
let port: number;
let server: ReturnType<Application['listen']>;
let jwproxy: JWProxy;
let wdproxy: WebDriverProxy;
let app: Application;
before(async function () {
@@ -474,10 +474,10 @@ describe('Protocol', function () {
const res = createProxyServer(port);
server = res.server;
app = res.app;
jwproxy = new JWProxy({server: TEST_HOST, port});
jwproxy.sessionId = sessionId;
wdproxy = new WebDriverProxy({server: TEST_HOST, port});
wdproxy.sessionId = sessionId;
(driver as any).performActions = async (actions: object[]) =>
await jwproxy.command('/perform-actions', 'POST', actions);
await wdproxy.command('/perform-actions', 'POST', actions);
});
afterEach(async function () {
@@ -841,7 +841,7 @@ describe('Protocol', function () {
assert.strictEqual(status, 200);
assert.ok(!driver.sessionId);
assert.strictEqual(driver.jwpProxyActive, false);
assert.strictEqual(driver.wdProxyActive, false);
});
it('should avoid proxying when command spec specifies neverProxy', async function () {
@@ -3,7 +3,7 @@ import {before, describe, it} from 'node:test';
import {getTestPort, TEST_HOST} from '@appium/driver-test-support';
import {JWProxy} from '../../../lib';
import {WebDriverProxy} from '../../../lib';
import {errors, isErrorType} from '../../../lib/protocol/errors';
import {type MockRequestOpts, request} from './mock-request';
@@ -42,7 +42,7 @@ describe('proxy', function () {
function mockProxy(opts: any = {}) {
// sets default server/port
opts = {server: TEST_HOST, port, ...opts};
const proxy = new JWProxy(opts);
const proxy = new WebDriverProxy(opts);
(proxy as any).request = async function (...args: any[]) {
return await request(args[0] as MockRequestOpts);
};
@@ -3,10 +3,10 @@ import {before, describe, it} from 'node:test';
import {getTestPort, TEST_HOST} from '@appium/driver-test-support';
import {JWProxy} from '../../../lib';
import {WebDriverProxy} from '../../../lib';
import {createAppiumURL} from '../../helpers';
describe('JWProxy', function () {
describe('WebDriverProxy', function () {
let port: number;
let createTestURL: (sessionId: string, path: string) => string;
let testStatusURL: string;
@@ -19,8 +19,8 @@ describe('JWProxy', function () {
const createProxyURL = createAppiumURL(PROXY_HOST, PROXY_PORT);
const PROXY_STATUS_URL = createProxyURL('', 'status');
function createJWProxy(opts: any = {}) {
return new JWProxy({server: TEST_HOST, port, ...opts});
function createWDProxy(opts: any = {}) {
return new WebDriverProxy({server: TEST_HOST, port, ...opts});
}
before(async function () {
@@ -34,31 +34,31 @@ describe('JWProxy', function () {
describe('proxying full urls', function () {
it('should translate host and port', function () {
const incomingUrl = PROXY_STATUS_URL;
const j = createJWProxy();
const j = createWDProxy();
const proxyUrl = j.getUrlForProxy(incomingUrl, 'GET');
assert.strictEqual(proxyUrl, testStatusURL);
});
it('should translate the scheme', function () {
const incomingUrl = PROXY_STATUS_URL;
const j = createJWProxy({scheme: 'HTTPS'});
const j = createWDProxy({scheme: 'HTTPS'});
const proxyUrl = j.getUrlForProxy(incomingUrl);
assert.strictEqual(proxyUrl, createAppiumURL(`https://${TEST_HOST}`, port, '', 'status'));
});
it('should translate the base', function () {
const incomingUrl = PROXY_STATUS_URL;
const j = createJWProxy({base: ''});
const j = createWDProxy({base: ''});
const proxyUrl = j.getUrlForProxy(incomingUrl, 'GET');
assert.strictEqual(proxyUrl, testStatusURL);
});
it('should translate the session id', function () {
const incomingUrl = createProxyURL('foobar', 'element');
const j = createJWProxy({sessionId: 'barbaz'});
const j = createWDProxy({sessionId: 'barbaz'});
const proxyUrl = j.getUrlForProxy(incomingUrl, 'POST');
assert.strictEqual(proxyUrl, createTestURL('barbaz', 'element'));
});
it('should error when translating session commands without session id', function () {
const incomingUrl = createProxyURL('foobar', 'element');
const j = createJWProxy();
const j = createWDProxy();
assert.throws(() => j.getUrlForProxy(incomingUrl, 'POST'), /not set/);
});
});
@@ -66,62 +66,62 @@ describe('JWProxy', function () {
describe('proxying partial urls', function () {
it('should proxy /status', function () {
const incomingUrl = '/status';
const j = createJWProxy();
const j = createWDProxy();
const proxyUrl = j.getUrlForProxy(incomingUrl, 'GET');
assert.strictEqual(proxyUrl, testStatusURL);
});
it('should proxy /session', function () {
const incomingUrl = '/session';
const j = createJWProxy();
const j = createWDProxy();
const proxyUrl = j.getUrlForProxy(incomingUrl);
assert.strictEqual(proxyUrl, testNewSessionURL);
});
it('should proxy session commands based off /session', function () {
const incomingUrl = '/session/foobar/element';
const j = createJWProxy({sessionId: 'barbaz'});
const j = createWDProxy({sessionId: 'barbaz'});
const proxyUrl = j.getUrlForProxy(incomingUrl, 'POST');
assert.strictEqual(proxyUrl, createTestURL('barbaz', 'element'));
});
it('should error session commands based off /session without session id', function () {
const incomingUrl = '/session/foobar/element';
const j = createJWProxy();
const j = createWDProxy();
assert.throws(() => j.getUrlForProxy(incomingUrl, 'POST'), /not set/);
});
it('should proxy session commands based off ', function () {
const incomingUrl = '/session/3d001db2-7987-42a7-975d-8d5d5304083f/timeouts/implicit_wait';
const j = createJWProxy({sessionId: '123'});
const j = createWDProxy({sessionId: '123'});
const proxyUrl = j.getUrlForProxy(incomingUrl, 'POST');
assert.strictEqual(proxyUrl, createTestURL('123', 'timeouts/implicit_wait'));
});
it('should proxy session commands based off /session as ""', function () {
const incomingUrl = '';
const j = createJWProxy();
const j = createWDProxy();
assert.throws(() => j.getUrlForProxy(incomingUrl, 'GET'), /not set/);
const j2 = createJWProxy({sessionId: '123'});
const j2 = createWDProxy({sessionId: '123'});
const proxyUrl = j2.getUrlForProxy(incomingUrl, 'GET');
assert.strictEqual(proxyUrl, createTestSessionURL('123'));
});
it('should proxy session commands without /session', function () {
const incomingUrl = '/element';
const j = createJWProxy({sessionId: 'barbaz'});
const j = createWDProxy({sessionId: 'barbaz'});
const proxyUrl = j.getUrlForProxy(incomingUrl, 'POST');
assert.strictEqual(proxyUrl, createTestURL('barbaz', 'element'));
});
it(`should proxy session commands when '/session' is in the url`, function () {
const incomingUrl = '/session/82a9b7da-faaf-4a1d-8ef3-5e4fb5812200/cookie/session-something-or-other';
const j = createJWProxy({sessionId: 'barbaz'});
const j = createWDProxy({sessionId: 'barbaz'});
const proxyUrl = j.getUrlForProxy(incomingUrl, 'POST');
assert.strictEqual(proxyUrl, createTestURL('barbaz', 'cookie/session-something-or-other'));
});
it(`should proxy session commands when '/session' is in the url and not base on the original url`, function () {
const incomingUrl = '/session/82a9b7da-faaf-4a1d-8ef3-5e4fb5812200/cookie/session-something-or-other';
const j = createJWProxy({sessionId: 'barbaz'});
const j = createWDProxy({sessionId: 'barbaz'});
const proxyUrl = j.getUrlForProxy(incomingUrl, 'POST');
assert.strictEqual(proxyUrl, createTestURL('barbaz', 'cookie/session-something-or-other'));
});
it('should error session commands without /session without session id', function () {
const incomingUrl = '/element';
const j = createJWProxy();
const j = createWDProxy();
assert.throws(() => j.getUrlForProxy(incomingUrl, 'POST'), /not set/);
});
});