Bug 1767387 - [remote-bidi] Also await browser startup finished when creating a newsession from Marionette. r=webdriver-reviewers,jdescottes

Previously the check has been added when starting the protocol.
But given that httpd.js gets started already in final-ui-startup
a new BiDi session request from Marionette can add required
path handlers, which results in accepting incoming commands
even with the browser not fully started up yet.

Differential Revision: https://phabricator.services.mozilla.com/D145311
This commit is contained in:
Henrik Skupin 2022-05-04 04:28:49 +00:00
parent 22d7c6a0be
commit 20249ab796
4 changed files with 24 additions and 18 deletions

View File

@ -362,7 +362,11 @@ class RemoteAgentParentProcess {
// Used to wait until the initial application window has been opened.
case "browser-idle-startup-tasks-finished":
case "mail-idle-startup-tasks-finished":
Services.obs.removeObserver(this, topic);
Services.obs.removeObserver(
this,
"browser-idle-startup-tasks-finished"
);
Services.obs.removeObserver(this, "mail-idle-startup-tasks-finished");
this.#browserStartupFinished.resolve();
break;

View File

@ -416,7 +416,7 @@ GeckoDriver.prototype.newSession = async function(cmd) {
// itself needs to handle it, and has to nullify the "webSocketUrl"
// capability.
if (RemoteAgent.webDriverBiDi) {
RemoteAgent.webDriverBiDi.createSession(capabilities);
await RemoteAgent.webDriverBiDi.createSession(capabilities);
} else {
this._currentSession = new WebDriverSession(capabilities);
this._currentSession.capabilities.delete("webSocketUrl");

View File

@ -78,26 +78,34 @@ class WebDriverBiDi {
* @throws {SessionNotCreatedError}
* If, for whatever reason, a session could not be created.
*/
createSession(capabilities, sessionlessConnection) {
async createSession(capabilities, sessionlessConnection) {
if (this.session) {
throw new error.SessionNotCreatedError(
"Maximum number of active sessions"
);
}
this._session = new WebDriverSession(capabilities, sessionlessConnection);
const session = new WebDriverSession(capabilities, sessionlessConnection);
// 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.running &&
(this.session.capabilities.get("webSocketUrl") || sessionlessConnection)
(session.capabilities.get("webSocketUrl") || sessionlessConnection)
) {
this.agent.server.registerPathHandler(this.session.path, this.session);
webSocketUrl = `${this.address}${this.session.path}`;
// Creating a WebDriver BiDi session too early can cause issues with
// clients in not being able to find any available browsing context.
// Also when closing the application while it's still starting up can
// cause shutdown hangs. As such WebDriver BiDi will return a new session
// once the initial application window has finished initializing.
logger.debug(`Waiting for initial application window to be loaded`);
await this.agent.browserStartupFinished;
logger.debug(`Registered session handler: ${this.session.path}`);
this.agent.server.registerPathHandler(session.path, session);
webSocketUrl = `${this.address}${session.path}`;
logger.debug(`Registered session handler: ${session.path}`);
if (sessionlessConnection) {
// Remove temporary session-less connection
@ -107,7 +115,9 @@ class WebDriverBiDi {
// 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);
session.capabilities.set("webSocketUrl", webSocketUrl);
this._session = session;
return {
sessionId: this.session.id,
@ -166,14 +176,6 @@ class WebDriverBiDi {
return;
}
// Creating a WebDriver BiDi session too early can cause issues with
// clients in not being able to find any available browsing context.
// Also when closing the application while it's still starting up can
// cause shutdown hangs. As such WebDriver BiDi will return a new session
// once the initial application window has finished initializing.
logger.debug(`Waiting for initial application window to be loaded`);
await this.agent.browserStartupFinished;
this._running = true;
// Install a HTTP handler for direct WebDriver BiDi connection requests.

View File

@ -165,7 +165,7 @@ class WebDriverBiDiConnection extends WebSocketConnection {
// Handle static commands first
if (module === "session" && command === "new") {
// TODO: Needs capability matching code
result = RemoteAgent.webDriverBiDi.createSession(params, this);
result = await RemoteAgent.webDriverBiDi.createSession(params, this);
} else if (module === "session" && command === "status") {
result = RemoteAgent.webDriverBiDi.getSessionReadinessStatus();
} else {