summaryrefslogtreecommitdiffstats
path: root/remote/shared/webdriver/test/xpcshell/test_Capabilities.js
diff options
context:
space:
mode:
Diffstat (limited to 'remote/shared/webdriver/test/xpcshell/test_Capabilities.js')
-rw-r--r--remote/shared/webdriver/test/xpcshell/test_Capabilities.js700
1 files changed, 700 insertions, 0 deletions
diff --git a/remote/shared/webdriver/test/xpcshell/test_Capabilities.js b/remote/shared/webdriver/test/xpcshell/test_Capabilities.js
new file mode 100644
index 0000000000..19401dd463
--- /dev/null
+++ b/remote/shared/webdriver/test/xpcshell/test_Capabilities.js
@@ -0,0 +1,700 @@
+/* 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";
+
+const { AppInfo } = ChromeUtils.importESModule(
+ "chrome://remote/content/shared/AppInfo.sys.mjs"
+);
+const { error } = ChromeUtils.importESModule(
+ "chrome://remote/content/shared/webdriver/Errors.sys.mjs"
+);
+const {
+ Capabilities,
+ mergeCapabilities,
+ PageLoadStrategy,
+ processCapabilities,
+ Proxy,
+ Timeouts,
+ UnhandledPromptBehavior,
+ validateCapabilities,
+} = ChromeUtils.importESModule(
+ "chrome://remote/content/shared/webdriver/Capabilities.sys.mjs"
+);
+
+add_task(function test_Timeouts_ctor() {
+ let ts = new Timeouts();
+ equal(ts.implicit, 0);
+ equal(ts.pageLoad, 300000);
+ equal(ts.script, 30000);
+});
+
+add_task(function test_Timeouts_toString() {
+ equal(new Timeouts().toString(), "[object Timeouts]");
+});
+
+add_task(function test_Timeouts_toJSON() {
+ let ts = new Timeouts();
+ deepEqual(ts.toJSON(), { implicit: 0, pageLoad: 300000, script: 30000 });
+});
+
+add_task(function test_Timeouts_fromJSON() {
+ let json = {
+ implicit: 0,
+ pageLoad: 2.0,
+ script: Number.MAX_SAFE_INTEGER,
+ };
+ let ts = Timeouts.fromJSON(json);
+ equal(ts.implicit, json.implicit);
+ equal(ts.pageLoad, json.pageLoad);
+ equal(ts.script, json.script);
+});
+
+add_task(function test_Timeouts_fromJSON_unrecognised_field() {
+ let json = {
+ sessionId: "foobar",
+ };
+ try {
+ Timeouts.fromJSON(json);
+ } catch (e) {
+ equal(e.name, error.InvalidArgumentError.name);
+ equal(e.message, "Unrecognised timeout: sessionId");
+ }
+});
+
+add_task(function test_Timeouts_fromJSON_invalid_types() {
+ for (let value of [null, [], {}, false, "10", 2.5]) {
+ Assert.throws(
+ () => Timeouts.fromJSON({ implicit: value }),
+ /InvalidArgumentError/
+ );
+ }
+});
+
+add_task(function test_Timeouts_fromJSON_bounds() {
+ for (let value of [-1, Number.MAX_SAFE_INTEGER + 1]) {
+ Assert.throws(
+ () => Timeouts.fromJSON({ script: value }),
+ /InvalidArgumentError/
+ );
+ }
+});
+
+add_task(function test_PageLoadStrategy() {
+ equal(PageLoadStrategy.None, "none");
+ equal(PageLoadStrategy.Eager, "eager");
+ equal(PageLoadStrategy.Normal, "normal");
+});
+
+add_task(function test_Proxy_ctor() {
+ let p = new Proxy();
+ let props = [
+ "proxyType",
+ "httpProxy",
+ "sslProxy",
+ "socksProxy",
+ "socksVersion",
+ "proxyAutoconfigUrl",
+ ];
+ for (let prop of props) {
+ ok(prop in p, `${prop} in ${JSON.stringify(props)}`);
+ equal(p[prop], null);
+ }
+});
+
+add_task(function test_Proxy_init() {
+ let p = new Proxy();
+
+ // no changed made, and 5 (system) is default
+ equal(p.init(), false);
+ equal(Services.prefs.getIntPref("network.proxy.type"), 5);
+
+ // pac
+ p.proxyType = "pac";
+ p.proxyAutoconfigUrl = "http://localhost:1234";
+ ok(p.init());
+
+ equal(Services.prefs.getIntPref("network.proxy.type"), 2);
+ equal(
+ Services.prefs.getStringPref("network.proxy.autoconfig_url"),
+ "http://localhost:1234"
+ );
+
+ // direct
+ p = new Proxy();
+ p.proxyType = "direct";
+ ok(p.init());
+ equal(Services.prefs.getIntPref("network.proxy.type"), 0);
+
+ // autodetect
+ p = new Proxy();
+ p.proxyType = "autodetect";
+ ok(p.init());
+ equal(Services.prefs.getIntPref("network.proxy.type"), 4);
+
+ // system
+ p = new Proxy();
+ p.proxyType = "system";
+ ok(p.init());
+ equal(Services.prefs.getIntPref("network.proxy.type"), 5);
+
+ // manual
+ for (let proxy of ["http", "ssl", "socks"]) {
+ p = new Proxy();
+ p.proxyType = "manual";
+ p.noProxy = ["foo", "bar"];
+ p[`${proxy}Proxy`] = "foo";
+ p[`${proxy}ProxyPort`] = 42;
+ if (proxy === "socks") {
+ p[`${proxy}Version`] = 4;
+ }
+
+ ok(p.init());
+ equal(Services.prefs.getIntPref("network.proxy.type"), 1);
+ equal(
+ Services.prefs.getStringPref("network.proxy.no_proxies_on"),
+ "foo, bar"
+ );
+ equal(Services.prefs.getStringPref(`network.proxy.${proxy}`), "foo");
+ equal(Services.prefs.getIntPref(`network.proxy.${proxy}_port`), 42);
+ if (proxy === "socks") {
+ equal(Services.prefs.getIntPref(`network.proxy.${proxy}_version`), 4);
+ }
+ }
+
+ // empty no proxy should reset default exclustions
+ p = new Proxy();
+ p.proxyType = "manual";
+ p.noProxy = [];
+ ok(p.init());
+ equal(Services.prefs.getStringPref("network.proxy.no_proxies_on"), "");
+});
+
+add_task(function test_Proxy_toString() {
+ equal(new Proxy().toString(), "[object Proxy]");
+});
+
+add_task(function test_Proxy_toJSON() {
+ let p = new Proxy();
+ deepEqual(p.toJSON(), {});
+
+ // autoconfig url
+ p = new Proxy();
+ p.proxyType = "pac";
+ p.proxyAutoconfigUrl = "foo";
+ deepEqual(p.toJSON(), { proxyType: "pac", proxyAutoconfigUrl: "foo" });
+
+ // manual proxy
+ p = new Proxy();
+ p.proxyType = "manual";
+ deepEqual(p.toJSON(), { proxyType: "manual" });
+
+ for (let proxy of ["httpProxy", "sslProxy", "socksProxy"]) {
+ let expected = { proxyType: "manual" };
+
+ p = new Proxy();
+ p.proxyType = "manual";
+
+ if (proxy == "socksProxy") {
+ p.socksVersion = 5;
+ expected.socksVersion = 5;
+ }
+
+ // without port
+ p[proxy] = "foo";
+ expected[proxy] = "foo";
+ deepEqual(p.toJSON(), expected);
+
+ // with port
+ p[proxy] = "foo";
+ p[`${proxy}Port`] = 0;
+ expected[proxy] = "foo:0";
+ deepEqual(p.toJSON(), expected);
+
+ p[`${proxy}Port`] = 42;
+ expected[proxy] = "foo:42";
+ deepEqual(p.toJSON(), expected);
+
+ // add brackets for IPv6 address as proxy hostname
+ p[proxy] = "2001:db8::1";
+ p[`${proxy}Port`] = 42;
+ expected[proxy] = "foo:42";
+ expected[proxy] = "[2001:db8::1]:42";
+ deepEqual(p.toJSON(), expected);
+ }
+
+ // noProxy: add brackets for IPv6 address
+ p = new Proxy();
+ p.proxyType = "manual";
+ p.noProxy = ["2001:db8::1"];
+ let expected = { proxyType: "manual", noProxy: "[2001:db8::1]" };
+ deepEqual(p.toJSON(), expected);
+});
+
+add_task(function test_Proxy_fromJSON() {
+ let p = new Proxy();
+ deepEqual(p, Proxy.fromJSON(undefined));
+ deepEqual(p, Proxy.fromJSON(null));
+
+ for (let typ of [true, 42, "foo", []]) {
+ Assert.throws(() => Proxy.fromJSON(typ), /InvalidArgumentError/);
+ }
+
+ // must contain a valid proxyType
+ Assert.throws(() => Proxy.fromJSON({}), /InvalidArgumentError/);
+ Assert.throws(
+ () => Proxy.fromJSON({ proxyType: "foo" }),
+ /InvalidArgumentError/
+ );
+
+ // autoconfig url
+ for (let url of [true, 42, [], {}]) {
+ Assert.throws(
+ () => Proxy.fromJSON({ proxyType: "pac", proxyAutoconfigUrl: url }),
+ /InvalidArgumentError/
+ );
+ }
+
+ p = new Proxy();
+ p.proxyType = "pac";
+ p.proxyAutoconfigUrl = "foo";
+ deepEqual(p, Proxy.fromJSON({ proxyType: "pac", proxyAutoconfigUrl: "foo" }));
+
+ // manual proxy
+ p = new Proxy();
+ p.proxyType = "manual";
+ deepEqual(p, Proxy.fromJSON({ proxyType: "manual" }));
+
+ for (let proxy of ["httpProxy", "sslProxy", "socksProxy"]) {
+ let manual = { proxyType: "manual" };
+
+ // invalid hosts
+ for (let host of [
+ true,
+ 42,
+ [],
+ {},
+ null,
+ "http://foo",
+ "foo:-1",
+ "foo:65536",
+ "foo/test",
+ "foo#42",
+ "foo?foo=bar",
+ "2001:db8::1",
+ ]) {
+ manual[proxy] = host;
+ Assert.throws(() => Proxy.fromJSON(manual), /InvalidArgumentError/);
+ }
+
+ p = new Proxy();
+ p.proxyType = "manual";
+ if (proxy == "socksProxy") {
+ manual.socksVersion = 5;
+ p.socksVersion = 5;
+ }
+
+ let host_map = {
+ "foo:1": { hostname: "foo", port: 1 },
+ "foo:21": { hostname: "foo", port: 21 },
+ "foo:80": { hostname: "foo", port: 80 },
+ "foo:443": { hostname: "foo", port: 443 },
+ "foo:65535": { hostname: "foo", port: 65535 },
+ "127.0.0.1:42": { hostname: "127.0.0.1", port: 42 },
+ "[2001:db8::1]:42": { hostname: "2001:db8::1", port: "42" },
+ };
+
+ // valid proxy hosts with port
+ for (let host in host_map) {
+ manual[proxy] = host;
+
+ p[`${proxy}`] = host_map[host].hostname;
+ p[`${proxy}Port`] = host_map[host].port;
+
+ deepEqual(p, Proxy.fromJSON(manual));
+ }
+
+ // Without a port the default port of the scheme is used
+ for (let host of ["foo", "foo:"]) {
+ manual[proxy] = host;
+
+ // For socks no default port is available
+ p[proxy] = `foo`;
+ if (proxy === "socksProxy") {
+ p[`${proxy}Port`] = null;
+ } else {
+ let default_ports = { httpProxy: 80, sslProxy: 443 };
+
+ p[`${proxy}Port`] = default_ports[proxy];
+ }
+
+ deepEqual(p, Proxy.fromJSON(manual));
+ }
+ }
+
+ // missing required socks version
+ Assert.throws(
+ () => Proxy.fromJSON({ proxyType: "manual", socksProxy: "foo:1234" }),
+ /InvalidArgumentError/
+ );
+
+ // Bug 1703805: Since Firefox 90 ftpProxy is no longer supported
+ Assert.throws(
+ () => Proxy.fromJSON({ proxyType: "manual", ftpProxy: "foo:21" }),
+ /InvalidArgumentError/
+ );
+
+ // noProxy: invalid settings
+ for (let noProxy of [true, 42, {}, null, "foo", [true], [42], [{}], [null]]) {
+ Assert.throws(
+ () => Proxy.fromJSON({ proxyType: "manual", noProxy }),
+ /InvalidArgumentError/
+ );
+ }
+
+ // noProxy: valid settings
+ p = new Proxy();
+ p.proxyType = "manual";
+ for (let noProxy of [[], ["foo"], ["foo", "bar"], ["127.0.0.1"]]) {
+ let manual = { proxyType: "manual", noProxy };
+ p.noProxy = noProxy;
+ deepEqual(p, Proxy.fromJSON(manual));
+ }
+
+ // noProxy: IPv6 needs brackets removed
+ p = new Proxy();
+ p.proxyType = "manual";
+ p.noProxy = ["2001:db8::1"];
+ let manual = { proxyType: "manual", noProxy: ["[2001:db8::1]"] };
+ deepEqual(p, Proxy.fromJSON(manual));
+});
+
+add_task(function test_UnhandledPromptBehavior() {
+ equal(UnhandledPromptBehavior.Accept, "accept");
+ equal(UnhandledPromptBehavior.AcceptAndNotify, "accept and notify");
+ equal(UnhandledPromptBehavior.Dismiss, "dismiss");
+ equal(UnhandledPromptBehavior.DismissAndNotify, "dismiss and notify");
+ equal(UnhandledPromptBehavior.Ignore, "ignore");
+});
+
+add_task(function test_Capabilities_ctor() {
+ let caps = new Capabilities();
+ ok(caps.has("browserName"));
+ ok(caps.has("browserVersion"));
+ ok(caps.has("platformName"));
+ ok(["linux", "mac", "windows", "android"].includes(caps.get("platformName")));
+ equal(PageLoadStrategy.Normal, caps.get("pageLoadStrategy"));
+ equal(false, caps.get("acceptInsecureCerts"));
+ ok(caps.get("timeouts") instanceof Timeouts);
+ 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"));
+ ok(caps.has("moz:debuggerAddress"));
+ ok(caps.has("moz:platformVersion"));
+ ok(caps.has("moz:processID"));
+ ok(caps.has("moz:profile"));
+ equal(true, caps.get("moz:webdriverClick"));
+
+ // No longer supported capabilities
+ ok(!caps.has("moz:useNonSpecCompliantPointerOrigin"));
+});
+
+add_task(function test_Capabilities_toString() {
+ equal("[object Capabilities]", new Capabilities().toString());
+});
+
+add_task(function test_Capabilities_toJSON() {
+ let caps = new Capabilities();
+ let json = caps.toJSON();
+
+ equal(caps.get("browserName"), json.browserName);
+ equal(caps.get("browserVersion"), json.browserVersion);
+ equal(caps.get("platformName"), json.platformName);
+ equal(caps.get("pageLoadStrategy"), json.pageLoadStrategy);
+ equal(caps.get("acceptInsecureCerts"), json.acceptInsecureCerts);
+ deepEqual(caps.get("proxy").toJSON(), json.proxy);
+ 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"]);
+ equal(caps.get("moz:debuggerAddress"), json["moz:debuggerAddress"]);
+ equal(caps.get("moz:platformVersion"), json["moz:platformVersion"]);
+ equal(caps.get("moz:processID"), json["moz:processID"]);
+ equal(caps.get("moz:profile"), json["moz:profile"]);
+ equal(caps.get("moz:webdriverClick"), json["moz:webdriverClick"]);
+});
+
+add_task(function test_Capabilities_fromJSON() {
+ const { fromJSON } = Capabilities;
+
+ // plain
+ for (let typ of [{}, null, undefined]) {
+ ok(fromJSON(typ).has("browserName"));
+ }
+
+ // matching
+ let caps = new Capabilities();
+
+ caps = fromJSON({ acceptInsecureCerts: true });
+ equal(true, caps.get("acceptInsecureCerts"));
+ caps = fromJSON({ acceptInsecureCerts: false });
+ equal(false, caps.get("acceptInsecureCerts"));
+
+ for (let strategy of Object.values(PageLoadStrategy)) {
+ caps = fromJSON({ pageLoadStrategy: strategy });
+ equal(strategy, caps.get("pageLoadStrategy"));
+ }
+
+ let proxyConfig = { proxyType: "manual" };
+ caps = fromJSON({ proxy: proxyConfig });
+ equal("manual", caps.get("proxy").proxyType);
+
+ let timeoutsConfig = { implicit: 123 };
+ caps = fromJSON({ timeouts: timeoutsConfig });
+ equal(123, caps.get("timeouts").implicit);
+
+ caps = fromJSON({ strictFileInteractability: false });
+ equal(false, caps.get("strictFileInteractability"));
+ caps = fromJSON({ strictFileInteractability: true });
+ equal(true, caps.get("strictFileInteractability"));
+
+ caps = fromJSON({ webSocketUrl: true });
+ equal(true, caps.get("webSocketUrl"));
+
+ caps = fromJSON({ "webauthn:virtualAuthenticators": true });
+ equal(true, caps.get("webauthn:virtualAuthenticators"));
+ caps = fromJSON({ "webauthn:virtualAuthenticators": false });
+ equal(false, caps.get("webauthn:virtualAuthenticators"));
+ Assert.throws(
+ () => fromJSON({ "webauthn:virtualAuthenticators": "foo" }),
+ /InvalidArgumentError/
+ );
+
+ caps = fromJSON({ "webauthn:extension:uvm": true });
+ equal(true, caps.get("webauthn:extension:uvm"));
+ caps = fromJSON({ "webauthn:extension:uvm": false });
+ equal(false, caps.get("webauthn:extension:uvm"));
+ Assert.throws(
+ () => fromJSON({ "webauthn:extension:uvm": "foo" }),
+ /InvalidArgumentError/
+ );
+
+ caps = fromJSON({ "webauthn:extension:prf": true });
+ equal(true, caps.get("webauthn:extension:prf"));
+ caps = fromJSON({ "webauthn:extension:prf": false });
+ equal(false, caps.get("webauthn:extension:prf"));
+ Assert.throws(
+ () => fromJSON({ "webauthn:extension:prf": "foo" }),
+ /InvalidArgumentError/
+ );
+
+ caps = fromJSON({ "webauthn:extension:largeBlob": true });
+ equal(true, caps.get("webauthn:extension:largeBlob"));
+ caps = fromJSON({ "webauthn:extension:largeBlob": false });
+ equal(false, caps.get("webauthn:extension:largeBlob"));
+ Assert.throws(
+ () => fromJSON({ "webauthn:extension:largeBlob": "foo" }),
+ /InvalidArgumentError/
+ );
+
+ caps = fromJSON({ "webauthn:extension:credBlob": true });
+ equal(true, caps.get("webauthn:extension:credBlob"));
+ caps = fromJSON({ "webauthn:extension:credBlob": false });
+ equal(false, caps.get("webauthn:extension:credBlob"));
+ Assert.throws(
+ () => fromJSON({ "webauthn:extension:credBlob": "foo" }),
+ /InvalidArgumentError/
+ );
+
+ caps = fromJSON({ "moz:accessibilityChecks": true });
+ equal(true, caps.get("moz:accessibilityChecks"));
+ caps = fromJSON({ "moz:accessibilityChecks": false });
+ equal(false, caps.get("moz:accessibilityChecks"));
+
+ // capability is always populated with null if remote agent is not listening
+ caps = fromJSON({});
+ equal(null, caps.get("moz:debuggerAddress"));
+ caps = fromJSON({ "moz:debuggerAddress": "foo" });
+ equal(null, caps.get("moz:debuggerAddress"));
+ caps = fromJSON({ "moz:debuggerAddress": true });
+ equal(null, caps.get("moz:debuggerAddress"));
+
+ caps = fromJSON({ "moz:webdriverClick": true });
+ equal(true, caps.get("moz:webdriverClick"));
+ caps = fromJSON({ "moz:webdriverClick": false });
+ equal(false, caps.get("moz:webdriverClick"));
+
+ // No longer supported capabilities
+ Assert.throws(
+ () => fromJSON({ "moz:useNonSpecCompliantPointerOrigin": false }),
+ /InvalidArgumentError/
+ );
+ Assert.throws(
+ () => fromJSON({ "moz:useNonSpecCompliantPointerOrigin": true }),
+ /InvalidArgumentError/
+ );
+});
+
+add_task(function test_mergeCapabilities() {
+ // Shadowed values.
+ Assert.throws(
+ () =>
+ mergeCapabilities(
+ { acceptInsecureCerts: true },
+ { acceptInsecureCerts: false }
+ ),
+ /InvalidArgumentError/
+ );
+
+ deepEqual(
+ { acceptInsecureCerts: true },
+ mergeCapabilities({ acceptInsecureCerts: true }, undefined)
+ );
+ deepEqual(
+ { acceptInsecureCerts: true, browserName: "Firefox" },
+ mergeCapabilities({ acceptInsecureCerts: true }, { browserName: "Firefox" })
+ );
+});
+
+add_task(function test_validateCapabilities_invalid() {
+ const invalidCapabilities = [
+ true,
+ 42,
+ "foo",
+ [],
+ { acceptInsecureCerts: "foo" },
+ { browserName: true },
+ { browserVersion: true },
+ { platformName: true },
+ { pageLoadStrategy: "foo" },
+ { proxy: false },
+ { strictFileInteractability: "foo" },
+ { timeouts: false },
+ { unhandledPromptBehavior: false },
+ { webSocketUrl: false },
+ { webSocketUrl: "foo" },
+ { "moz:firefoxOptions": "foo" },
+ { "moz:accessibilityChecks": "foo" },
+ { "moz:webdriverClick": "foo" },
+ { "moz:webdriverClick": 1 },
+ { "moz:useNonSpecCompliantPointerOrigin": false },
+ { "moz:debuggerAddress": "foo" },
+ { "moz:someRandomString": {} },
+ ];
+ for (const capabilities of invalidCapabilities) {
+ Assert.throws(
+ () => validateCapabilities(capabilities),
+ /InvalidArgumentError/
+ );
+ }
+});
+
+add_task(function test_validateCapabilities_valid() {
+ // Ignore null value.
+ deepEqual({}, validateCapabilities({ test: null }));
+
+ const validCapabilities = [
+ { acceptInsecureCerts: true },
+ { browserName: "firefox" },
+ { browserVersion: "12" },
+ { platformName: "linux" },
+ { pageLoadStrategy: "eager" },
+ { proxy: { proxyType: "manual", httpProxy: "test.com" } },
+ { strictFileInteractability: true },
+ { timeouts: { pageLoad: 500 } },
+ { unhandledPromptBehavior: "accept" },
+ { webSocketUrl: true },
+ { "moz:firefoxOptions": {} },
+ { "moz:accessibilityChecks": true },
+ { "moz:webdriverClick": true },
+ { "moz:debuggerAddress": true },
+ { "test:extension": "foo" },
+ ];
+ for (const validCapability of validCapabilities) {
+ deepEqual(validCapability, validateCapabilities(validCapability));
+ }
+});
+
+add_task(function test_processCapabilities() {
+ for (const invalidValue of [
+ { capabilities: null },
+ { capabilities: undefined },
+ { capabilities: "foo" },
+ { capabilities: true },
+ { capabilities: [] },
+ { capabilities: { alwaysMatch: null } },
+ { capabilities: { alwaysMatch: "foo" } },
+ { capabilities: { alwaysMatch: true } },
+ { capabilities: { alwaysMatch: [] } },
+ { capabilities: { firstMatch: null } },
+ { capabilities: { firstMatch: "foo" } },
+ { capabilities: { firstMatch: true } },
+ { capabilities: { firstMatch: {} } },
+ { capabilities: { firstMatch: [] } },
+ ]) {
+ Assert.throws(
+ () => processCapabilities(invalidValue),
+ /InvalidArgumentError/
+ );
+ }
+
+ deepEqual(
+ { acceptInsecureCerts: true },
+ processCapabilities({
+ capabilities: { alwaysMatch: { acceptInsecureCerts: true } },
+ })
+ );
+ deepEqual(
+ { browserName: "Firefox" },
+ processCapabilities({
+ capabilities: { firstMatch: [{ browserName: "Firefox" }] },
+ })
+ );
+ deepEqual(
+ { acceptInsecureCerts: true, browserName: "Firefox" },
+ processCapabilities({
+ capabilities: {
+ alwaysMatch: { acceptInsecureCerts: true },
+ firstMatch: [{ browserName: "Firefox" }],
+ },
+ })
+ );
+});
+
+// use Proxy.toJSON to test marshal
+add_task(function test_marshal() {
+ let proxy = new Proxy();
+
+ // drop empty fields
+ deepEqual({}, proxy.toJSON());
+ proxy.proxyType = "manual";
+ deepEqual({ proxyType: "manual" }, proxy.toJSON());
+ proxy.proxyType = null;
+ deepEqual({}, proxy.toJSON());
+ proxy.proxyType = undefined;
+ deepEqual({}, proxy.toJSON());
+
+ // iterate over object literals
+ proxy.proxyType = { foo: "bar" };
+ deepEqual({ proxyType: { foo: "bar" } }, proxy.toJSON());
+
+ // iterate over complex object that implement toJSON
+ proxy.proxyType = new Proxy();
+ deepEqual({}, proxy.toJSON());
+ proxy.proxyType.proxyType = "manual";
+ deepEqual({ proxyType: { proxyType: "manual" } }, proxy.toJSON());
+
+ // drop objects with no entries
+ proxy.proxyType = { foo: {} };
+ deepEqual({}, proxy.toJSON());
+ proxy.proxyType = { foo: new Proxy() };
+ deepEqual({}, proxy.toJSON());
+});