webdriver
Version:
A Node.js bindings implementation for the W3C WebDriver and Mobile JSONWire Protocol
67 lines (66 loc) • 2.35 kB
JavaScript
import WebSocket from 'ws';
import logger from '@wdio/logger';
const log = logger('webdriver');
const RESPONSE_TIMEOUT = 1000 * 60;
export class BidiCore {
_webSocketUrl;
#id = 0;
#ws;
#isConnected = false;
constructor(_webSocketUrl, opts) {
this._webSocketUrl = _webSocketUrl;
log.info(`Connect to webSocketUrl ${this._webSocketUrl}`);
this.#ws = new WebSocket(this._webSocketUrl, opts);
}
connect() {
return new Promise((resolve) => this.#ws.on('open', () => {
log.info('Connected session to Bidi protocol');
this.#isConnected = true;
resolve();
}));
}
get socket() {
return this.#ws;
}
get isConnected() {
return this.#isConnected;
}
send(params) {
const id = this.sendAsync(params);
const failError = new Error(`WebDriver Bidi command "${params.method}" failed`);
return new Promise((resolve, reject) => {
const t = setTimeout(() => {
reject(new Error(`Request with id ${id} timed out`));
h.off('message', listener);
}, RESPONSE_TIMEOUT);
const listener = (data) => {
try {
const payload = JSON.parse(data.toString());
if (payload.id === id) {
clearTimeout(t);
h.off('message', listener);
log.info('BIDI RESULT', JSON.stringify(payload));
if (payload.error) {
failError.message += ` with error: ${payload.error}`;
return reject(failError);
}
resolve(payload);
}
}
catch (err) {
log.error(`Failed parse message: ${err.message}`);
}
};
const h = this.#ws.on('message', listener);
});
}
sendAsync(params) {
if (!this.#isConnected) {
throw new Error('No connection to WebDriver Bidi was established');
}
log.info('BIDI COMMAND', params.method, JSON.stringify(params.params));
const id = ++this.#id;
this.#ws.send(JSON.stringify({ id, ...params }));
return id;
}
}