Skip to content

Commit

Permalink
Bug 1692984 - [marionette] Add support for “webSocketUrl” capability.…
Browse files Browse the repository at this point in the history
… r=webdriver-reviewers,jdescottes,jgraham

Differential Revision: https://phabricator.services.mozilla.com/D119730
  • Loading branch information
whimboo committed Jul 16, 2021
1 parent 02977a7 commit 908b1cb
Show file tree
Hide file tree
Showing 9 changed files with 90 additions and 21 deletions.
6 changes: 4 additions & 2 deletions remote/marionette/driver.js
Original file line number Diff line number Diff line change
Expand Up @@ -424,12 +424,14 @@ GeckoDriver.prototype.newSession = async function(cmd) {
this.mainFrame = win;

// If the WebDriver BiDi protocol is active always use the Remote Agent
// to handle the WebDriver session. If it's not the case Marionette itself
// needs to handle it.
// to handle the WebDriver session. If it's not the case then Marionette
// itself needs to handle it, and has to nullify the "webSocketUrl"
// capability.
if (RemoteAgent.webdriverBiDi) {
RemoteAgent.webdriverBiDi.createSession(capabilities);
} else {
this._currentSession = new WebDriverSession(capabilities);
this._currentSession.capabilities.delete("webSocketUrl");
}

registerCommandsActor();
Expand Down
12 changes: 9 additions & 3 deletions remote/shared/webdriver/Capabilities.jsm
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,7 @@ class Capabilities extends Map {
["timeouts", new Timeouts()],
["strictFileInteractability", false],
["unhandledPromptBehavior", UnhandledPromptBehavior.DismissAndNotify],
["webSocketUrl", null],

// proprietary
["moz:accessibilityChecks", false],
Expand Down Expand Up @@ -572,9 +573,14 @@ class Capabilities extends Map {
break;

case "webSocketUrl":
throw new error.InvalidArgumentError(
"webSocketURL is not supported yet"
);
assert.boolean(v, pprint`Expected ${k} to be boolean, got ${v}`);

if (!v) {
throw new error.InvalidArgumentError(
pprint`Expected ${k} to be true, got ${v}`
);
}
break;

case "moz:accessibilityChecks":
assert.boolean(v, pprint`Expected ${k} to be boolean, got ${v}`);
Expand Down
2 changes: 1 addition & 1 deletion remote/shared/webdriver/Session.jsm
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ class WebDriverSession {
this.path = `/session/${this.id}`;

try {
this.capabilities = Capabilities.fromJSON(capabilities);
this.capabilities = Capabilities.fromJSON(capabilities, this.path);
} catch (e) {
throw new error.SessionNotCreatedError(e);
}
Expand Down
14 changes: 13 additions & 1 deletion remote/shared/webdriver/test/xpcshell/test_Capabilities.js
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,7 @@ add_test(function test_Capabilities_ctor() {
ok(caps.get("proxy") instanceof Proxy);
equal(caps.get("setWindowRect"), !AppInfo.isAndroid);
equal(caps.get("strictFileInteractability"), false);
equal(caps.get("webSocketUrl"), null);

equal(false, caps.get("moz:accessibilityChecks"));
ok(caps.has("moz:buildID"));
Expand Down Expand Up @@ -449,6 +450,7 @@ add_test(function test_Capabilities_toJSON() {
deepEqual(caps.get("timeouts").toJSON(), json.timeouts);
equal(caps.get("setWindowRect"), json.setWindowRect);
equal(caps.get("strictFileInteractability"), json.strictFileInteractability);
equal(caps.get("webSocketUrl"), json.webSocketUrl);

equal(caps.get("moz:accessibilityChecks"), json["moz:accessibilityChecks"]);
equal(caps.get("moz:buildID"), json["moz:buildID"]);
Expand Down Expand Up @@ -527,6 +529,17 @@ add_test(function test_Capabilities_fromJSON() {
caps = fromJSON({ strictFileInteractability: true });
equal(true, caps.get("strictFileInteractability"));

caps = fromJSON({ webSocketUrl: true });
equal(true, caps.get("webSocketUrl"));
Assert.throws(
() => fromJSON({ webSocketUrl: false }),
/InvalidArgumentError/
);
Assert.throws(
() => fromJSON({ webSocketUrl: "foo" }),
/InvalidArgumentError/
);

caps = fromJSON({ "moz:accessibilityChecks": true });
equal(true, caps.get("moz:accessibilityChecks"));
caps = fromJSON({ "moz:accessibilityChecks": false });
Expand Down Expand Up @@ -573,7 +586,6 @@ add_test(function test_Capabilities_fromJSON() {
() => fromJSON({ "moz:webdriverClick": 1 }),
/InvalidArgumentError/
);
Assert.throws(() => fromJSON({ webSocketUrl: true }), /InvalidArgumentError/);

run_next_test();
});
Expand Down
17 changes: 13 additions & 4 deletions remote/webdriver-bidi/WebDriverBiDi.jsm
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,20 @@ class WebDriverBiDi {

this._session = new WebDriverSession(capabilities);

// Only register the path handler when the Remote Agent is active.
if (this.agent.listening) {
// 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")) {
this.agent.server.registerPathHandler(this.session.path, this.session);
webSocketUrl = `${this.address}${this.session.path}`;

logger.debug(`Registered session handler: ${this.session.path}`);
}

// 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);

return {
sessionId: this.session.id,
capabilities: this.session.capabilities,
Expand All @@ -91,8 +99,9 @@ class WebDriverBiDi {
return;
}

// Only unregister the path handler when the Remote Agent is active.
if (this.agent.listening) {
// 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")) {
this.agent.server.registerPathHandler(this.session.path, null);
logger.debug(`Unregistered session handler: ${this.session.path}`);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,6 @@ def test_unhandled_prompt_behavior(self):
self.marionette.start_session({"unhandledPromptBehavior": behavior})

def test_web_socket_url(self):
with self.assertRaisesRegexp(
SessionNotCreatedException, "InvalidArgumentError"
):
self.marionette.start_session({"webSocketUrl": True})
self.marionette.start_session({"webSocketUrl": True})
# Remote Agent is not active by default
self.assertNotIn("webSocketUrl", self.marionette.session_capabilities)
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,45 @@ def test_debugger_address_cdp_status(self):
result = requests.get(url="http://{}/json/version".format(debugger_address))
self.assertTrue(result.ok)

def test_websocket_url(self):
with self.marionette.using_context("chrome"):
bidi_enabled = self.marionette.execute_script(
"""
const { RemoteAgent } = ChromeUtils.import(
"chrome://remote/content/components/RemoteAgent.jsm"
);
return !!RemoteAgent.webdriverBiDi;
"""
)

# By default Remote Agent is not enabled
self.assertNotIn("webSocketUrl", self.marionette.session_capabilities)

# With BiDi not enabled the capability is still not returned
self.marionette.enforce_gecko_prefs({"remote.active-protocols": 2})
try:
self.marionette.quit()
self.marionette.instance.app_args.append("-remote-debugging-port")
self.marionette.start_session({"webSocketUrl": True})

self.assertNotIn("webSocketUrl", self.marionette.session_capabilities)
finally:
self.marionette.clear_pref("remote.active-protocols")
self.marionette.restart()

# With BiDi enabled the capability has to be returned
if bidi_enabled:
self.marionette.quit()
self.marionette.instance.switch_profile()
self.marionette.start_session({"webSocketUrl": True})

session_id = self.marionette.session_id
websocket_url = self.marionette.session_capabilities.get("webSocketUrl")

self.assertEqual(
websocket_url, "ws://localhost:9222/session/{}".format(session_id)
)

def test_start_in_safe_mode(self):
self.marionette.instance.app_args.append("-safe-mode")

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
[connect.py]
[test_websocket_url_connect[capabilities0\]]
expected: ERROR
expected:
if release_or_beta: ERROR

[test_bidi_session_send]
expected: ERROR
expected:
if release_or_beta: ERROR

[test_bidi_session_with_different_capability[capabilities0\]]
expected: ERROR

expected:
if release_or_beta: ERROR
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[websocket_url.py]
[test_websocket_url]
expected: FAIL

expected:
if release_or_beta: FAIL

0 comments on commit 908b1cb

Please sign in to comment.