2021-07-09 11:00:52 +03:00
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
|
|
|
|
"use strict";
|
|
|
|
|
|
|
|
var EXPORTED_SYMBOLS = ["WebDriverBiDi"];
|
|
|
|
|
|
|
|
const { XPCOMUtils } = ChromeUtils.import(
|
|
|
|
"resource://gre/modules/XPCOMUtils.jsm"
|
|
|
|
);
|
|
|
|
|
|
|
|
XPCOMUtils.defineLazyModuleGetters(this, {
|
|
|
|
Services: "resource://gre/modules/Services.jsm",
|
2021-07-16 14:56:48 +03:00
|
|
|
|
|
|
|
error: "chrome://remote/content/shared/webdriver/Errors.jsm",
|
|
|
|
Log: "chrome://remote/content/shared/Log.jsm",
|
|
|
|
WebDriverSession: "chrome://remote/content/shared/webdriver/Session.jsm",
|
2021-07-09 11:00:52 +03:00
|
|
|
});
|
|
|
|
|
2021-07-16 14:56:48 +03:00
|
|
|
XPCOMUtils.defineLazyGetter(this, "logger", () =>
|
|
|
|
Log.get(Log.TYPES.WEBDRIVER_BIDI)
|
|
|
|
);
|
|
|
|
|
2021-07-09 11:00:52 +03:00
|
|
|
/**
|
|
|
|
* Entry class for the WebDriver BiDi support.
|
|
|
|
*
|
|
|
|
* @see https://w3c.github.io/webdriver-bidi
|
|
|
|
*/
|
|
|
|
class WebDriverBiDi {
|
|
|
|
/**
|
|
|
|
* Creates a new instance of the WebDriverBiDi class.
|
|
|
|
*
|
|
|
|
* @param {RemoteAgent} agent
|
|
|
|
* Reference to the Remote Agent instance.
|
|
|
|
*/
|
|
|
|
constructor(agent) {
|
|
|
|
this.agent = agent;
|
2021-07-15 16:45:27 +03:00
|
|
|
this._running = false;
|
2021-07-16 14:56:48 +03:00
|
|
|
|
|
|
|
this._session = null;
|
2021-07-09 11:00:52 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
get address() {
|
|
|
|
return `ws://${this.agent.host}:${this.agent.port}`;
|
|
|
|
}
|
|
|
|
|
2021-07-16 14:56:48 +03:00
|
|
|
get session() {
|
|
|
|
return this._session;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Create a new WebDriver session.
|
|
|
|
*
|
|
|
|
* @param {Object.<string, *>=} capabilities
|
|
|
|
* JSON Object containing any of the recognised capabilities as listed
|
|
|
|
* on the `WebDriverSession` class.
|
|
|
|
*
|
|
|
|
* @return {Object<String, Capabilities>}
|
|
|
|
* Object containing the current session ID, and all its capabilities.
|
|
|
|
*
|
|
|
|
* @throws {SessionNotCreatedError}
|
|
|
|
* If, for whatever reason, a session could not be created.
|
|
|
|
*/
|
|
|
|
createSession(capabilities) {
|
|
|
|
if (this.session) {
|
|
|
|
throw new error.SessionNotCreatedError(
|
|
|
|
"Maximum number of active sessions"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
this._session = new WebDriverSession(capabilities);
|
|
|
|
|
2021-07-16 14:56:49 +03:00
|
|
|
// When the Remote Agent is listening, and a BiDi WebSocket connection
|
|
|
|
// has been requested, register a path handler for the session.
|
|
|
|
let webSocketUrl = null;
|
|
|
|
if (this.agent.listening && this.session.capabilities.get("webSocketUrl")) {
|
2021-07-16 14:56:48 +03:00
|
|
|
this.agent.server.registerPathHandler(this.session.path, this.session);
|
2021-07-16 14:56:49 +03:00
|
|
|
webSocketUrl = `${this.address}${this.session.path}`;
|
|
|
|
|
2021-07-16 14:56:48 +03:00
|
|
|
logger.debug(`Registered session handler: ${this.session.path}`);
|
|
|
|
}
|
|
|
|
|
2021-07-16 14:56:49 +03:00
|
|
|
// Also update the webSocketUrl capability to contain the session URL if
|
|
|
|
// a path handler has been registered. Otherwise set its value to null.
|
|
|
|
this.session.capabilities.set("webSocketUrl", webSocketUrl);
|
|
|
|
|
2021-07-16 14:56:48 +03:00
|
|
|
return {
|
|
|
|
sessionId: this.session.id,
|
|
|
|
capabilities: this.session.capabilities,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Delete the current WebDriver session.
|
|
|
|
*/
|
|
|
|
deleteSession() {
|
|
|
|
if (!this.session) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-07-16 14:56:49 +03:00
|
|
|
// When the Remote Agent is listening, and a BiDi WebSocket is active,
|
|
|
|
// unregister the path handler for the session.
|
|
|
|
if (this.agent.listening && this.session.capabilities.get("webSocketUrl")) {
|
2021-07-16 14:56:48 +03:00
|
|
|
this.agent.server.registerPathHandler(this.session.path, null);
|
|
|
|
logger.debug(`Unregistered session handler: ${this.session.path}`);
|
|
|
|
}
|
|
|
|
|
|
|
|
this.session.destroy();
|
|
|
|
this._session = null;
|
|
|
|
}
|
|
|
|
|
2021-07-09 11:00:52 +03:00
|
|
|
/**
|
|
|
|
* Starts the WebDriver BiDi support.
|
|
|
|
*/
|
|
|
|
start() {
|
2021-07-15 16:45:27 +03:00
|
|
|
if (this._running) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
this._running = true;
|
|
|
|
|
2021-07-09 11:00:52 +03:00
|
|
|
Services.obs.notifyObservers(
|
|
|
|
null,
|
|
|
|
"remote-listening",
|
|
|
|
`WebDriver BiDi listening on ${this.address}`
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Stops the WebDriver BiDi support.
|
|
|
|
*/
|
2021-07-15 16:45:27 +03:00
|
|
|
stop() {
|
|
|
|
if (!this._running) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-07-16 14:56:48 +03:00
|
|
|
try {
|
|
|
|
this.deleteSession();
|
|
|
|
} finally {
|
|
|
|
this._running = false;
|
|
|
|
}
|
2021-07-15 16:45:27 +03:00
|
|
|
}
|
2021-07-09 11:00:52 +03:00
|
|
|
}
|