Source code
Revision control
Copy as Markdown
Other Tools
Test Info:
<!DOCTYPE HTML>
<html>
<head>
  <title>Test feature policy - parsing</title>
  <script src="/tests/SimpleTest/SimpleTest.js"></script>
  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<iframe src="empty.html" id="ifr"></iframe>
<iframe src="https://example.org/tests/dom/security/featurePolicy/test/mochitest/empty.html" id="cross_ifr"></iframe>
<script type="text/javascript">
SimpleTest.waitForExplicitFinish();
function test_document() {
  info("Checking document.featurePolicy");
  ok("featurePolicy" in document, "We have document.featurePolicy");
  ok(!document.featurePolicy.allowsFeature("foobar"), "Random feature");
  ok(document.featurePolicy.allowsFeature("camera"), "Camera is allowed for self");
  let allowed = document.featurePolicy.getAllowlistForFeature("camera");
  is(allowed.length, 1, "Only 1 entry in allowlist for camera");
  is(allowed[0], "*", "allowlist is *");
  ok(document.featurePolicy.allowsFeature("geolocation"), "Geolocation is allowed for self");
  ok(document.featurePolicy.allowsFeature("geolocation", location.origin), "Geolocation is allowed for self");
  ok(!document.featurePolicy.allowsFeature("geolocation", "https://foo.bar"), "Geolocation is not allowed for any random URL");
  allowed = document.featurePolicy.getAllowlistForFeature("geolocation");
  is(allowed.length, 1, "Only 1 entry in allowlist for geolocation");
  is(allowed[0], location.origin, "allowlist is self");
  ok(!document.featurePolicy.allowsFeature("microphone"), "Microphone is disabled for self");
  ok(!document.featurePolicy.allowsFeature("microphone", location.origin), "Microphone is disabled for self");
  ok(!document.featurePolicy.allowsFeature("microphone", "https://foo.bar"), "Microphone is disabled for foo.bar");
  ok(document.featurePolicy.allowsFeature("microphone", "https://example.com"), "Microphone is allowed for example.com");
  ok(document.featurePolicy.allowsFeature("microphone", "https://example.org"), "Microphone is allowed for example.org");
  allowed = document.featurePolicy.getAllowlistForFeature("microphone");
  is(allowed.length, 0, "No allowlist for microphone");
  ok(!document.featurePolicy.allowsFeature("vr"), "Vibrate is disabled for self");
  ok(!document.featurePolicy.allowsFeature("vr", location.origin), "Vibrate is disabled for self");
  ok(!document.featurePolicy.allowsFeature("vr", "https://foo.bar"), "Vibrate is disabled for foo.bar");
  allowed = document.featurePolicy.getAllowlistForFeature("vr");
  is(allowed.length, 0, "No allowlist for vr");
  allowed = document.featurePolicy.allowedFeatures();
  // microphone is disabled for this origin, vr is disabled everywhere.
  let camera = false;
  let geolocation = false;
  allowed.forEach(a => {
    if (a == "camera") camera = true;
    if (a == "geolocation") geolocation = true;
  });
  ok(camera, "Camera is always allowed");
  ok(geolocation, "Geolocation is allowed only for self");
  next();
}
function test_iframe_without_allow() {
  info("Checking HTMLIFrameElement.featurePolicy");
  let ifr = document.getElementById("ifr");
  ok("featurePolicy" in ifr, "HTMLIFrameElement.featurePolicy exists");
  ok(!ifr.featurePolicy.allowsFeature("foobar"), "Random feature");
  ok(ifr.featurePolicy.allowsFeature("camera"), "Camera is allowed for self");
  ok(ifr.featurePolicy.allowsFeature("camera", location.origin), "Camera is allowed for self");
  ok(!ifr.featurePolicy.allowsFeature("camera", "https://foo.bar"), "Camera is not allowed for a random URL");
  let allowed = ifr.featurePolicy.getAllowlistForFeature("camera");
  is(allowed.length, 1, "Only 1 entry in allowlist for camera");
  is(allowed[0], location.origin, "allowlist is 'self'");
  ok(ifr.featurePolicy.allowsFeature("geolocation"), "Geolocation is allowed for self");
  ok(ifr.featurePolicy.allowsFeature("geolocation", location.origin), "Geolocation is allowed for self");
  ok(!ifr.featurePolicy.allowsFeature("geolocation", "https://foo.bar"), "Geolocation is not allowed for any random URL");
  allowed = ifr.featurePolicy.getAllowlistForFeature("geolocation");
  is(allowed.length, 1, "Only 1 entry in allowlist for geolocation");
  is(allowed[0], location.origin, "allowlist is '*'");
  ok(!ifr.featurePolicy.allowsFeature("microphone"), "Microphone is disabled for self");
  ok(!ifr.featurePolicy.allowsFeature("microphone", location.origin), "Microphone is disabled for self");
  ok(!ifr.featurePolicy.allowsFeature("microphone", "https://foo.bar"), "Microphone is disabled for foo.bar");
  ok(!ifr.featurePolicy.allowsFeature("microphone", "https://example.com"), "Microphone is disabled for example.com");
  ok(!ifr.featurePolicy.allowsFeature("microphone", "https://example.org"), "Microphone is disabled for example.org");
  allowed = ifr.featurePolicy.getAllowlistForFeature("microphone");
  is(allowed.length, 0, "No allowlist for microphone");
  ok(!ifr.featurePolicy.allowsFeature("vr"), "Vibrate is disabled for self");
  ok(!ifr.featurePolicy.allowsFeature("vr", location.origin), "Vibrate is disabled for self");
  allowed = ifr.featurePolicy.getAllowlistForFeature("vr");
  is(allowed.length, 0, "No allowlist for vr");
  ok(ifr.featurePolicy.allowedFeatures().includes("camera"), "Camera is allowed");
  ok(ifr.featurePolicy.allowedFeatures().includes("geolocation"), "Geolocation is allowed");
  // microphone is disabled for this origin
  ok(!ifr.featurePolicy.allowedFeatures().includes("microphone"), "microphone is not allowed");
  // vr is disabled everywhere.
  ok(!ifr.featurePolicy.allowedFeatures().includes("vr"), "VR is not allowed");
  next();
}
function test_iframe_with_allow() {
  info("Checking HTMLIFrameElement.featurePolicy");
  let ifr = document.getElementById("ifr");
  ok("featurePolicy" in ifr, "HTMLIFrameElement.featurePolicy exists");
  ifr.setAttribute("allow", "camera 'none'");
  ok(!ifr.featurePolicy.allowsFeature("foobar"), "Random feature");
  ok(!ifr.featurePolicy.allowsFeature("camera"), "Camera is not allowed");
  let allowed = ifr.featurePolicy.getAllowlistForFeature("camera");
  is(allowed.length, 0, "Camera has an empty allowlist");
  ok(ifr.featurePolicy.allowsFeature("geolocation"), "Geolocation is allowed for self");
  ok(ifr.featurePolicy.allowsFeature("geolocation", location.origin), "Geolocation is allowed for self");
  ok(!ifr.featurePolicy.allowsFeature("geolocation", "https://foo.bar"), "Geolocation is not allowed for any random URL");
  allowed = ifr.featurePolicy.getAllowlistForFeature("geolocation");
  is(allowed.length, 1, "Only 1 entry in allowlist for geolocation");
  is(allowed[0], location.origin, "allowlist is '*'");
  ok(!ifr.featurePolicy.allowsFeature("microphone"), "Microphone is disabled for self");
  ok(!ifr.featurePolicy.allowsFeature("microphone", location.origin), "Microphone is disabled for self");
  ok(!ifr.featurePolicy.allowsFeature("microphone", "https://foo.bar"), "Microphone is disabled for foo.bar");
  ok(!ifr.featurePolicy.allowsFeature("microphone", "https://example.com"), "Microphone is disabled for example.com");
  ok(!ifr.featurePolicy.allowsFeature("microphone", "https://example.org"), "Microphone is disabled for example.org");
  allowed = ifr.featurePolicy.getAllowlistForFeature("microphone");
  is(allowed.length, 0, "No allowlist for microphone");
  ok(!ifr.featurePolicy.allowsFeature("vr"), "Vibrate is disabled for self");
  ok(!ifr.featurePolicy.allowsFeature("vr", location.origin), "Vibrate is disabled for self");
  allowed = ifr.featurePolicy.getAllowlistForFeature("vr");
  is(allowed.length, 0, "No allowlist for vr");
  ok(ifr.featurePolicy.allowedFeatures().includes("geolocation"), "Geolocation is allowed only for self");
  next();
}
function test_iframe_contentDocument() {
  info("Checking iframe document.featurePolicy");
  let ifr = document.createElement("iframe");
  ifr.setAttribute("src", "empty.html");
  ifr.onload = function() {
    ok("featurePolicy" in ifr.contentDocument, "We have ifr.contentDocument.featurePolicy");
    ok(!ifr.contentDocument.featurePolicy.allowsFeature("foobar"), "Random feature");
    ok(!ifr.contentDocument.featurePolicy.allowsFeature("foobar", "https://www.something.net"), "Random feature");
    ok(ifr.contentDocument.featurePolicy.allowsFeature("camera"), "Camera is allowed for self");
    ok(ifr.contentDocument.featurePolicy.allowsFeature("camera", location.origin), "Camera is allowed for self");
    ok(!ifr.contentDocument.featurePolicy.allowsFeature("camera", "https://foo.bar"), "Camera is allowed for self");
    let allowed = ifr.contentDocument.featurePolicy.getAllowlistForFeature("camera");
    is(allowed.length, 1, "Only 1 entry in allowlist for camera");
    is(allowed[0], location.origin, "allowlist is 'self'");
    ok(ifr.featurePolicy.allowsFeature("geolocation"), "Geolocation is allowed for self");
    ok(ifr.featurePolicy.allowsFeature("geolocation", location.origin), "Geolocation is allowed for self");
    ok(!ifr.featurePolicy.allowsFeature("geolocation", "https://foo.bar"), "Geolocation is not allowed for any random URL");
    allowed = ifr.featurePolicy.getAllowlistForFeature("geolocation");
    is(allowed.length, 1, "Only 1 entry in allowlist for geolocation");
    is(allowed[0], location.origin, "allowlist is '*'");
    ok(!ifr.contentDocument.featurePolicy.allowsFeature("microphone"), "Microphone is disabled for self");
    ok(!ifr.contentDocument.featurePolicy.allowsFeature("microphone", location.origin), "Microphone is disabled for self");
    ok(!ifr.contentDocument.featurePolicy.allowsFeature("microphone", "https://foo.bar"), "Microphone is disabled for foo.bar");
    ok(!ifr.contentDocument.featurePolicy.allowsFeature("microphone", "https://example.com"), "Microphone is allowed for example.com");
    ok(!ifr.contentDocument.featurePolicy.allowsFeature("microphone", "https://example.org"), "Microphone is allowed for example.org");
    allowed = ifr.contentDocument.featurePolicy.getAllowlistForFeature("microphone");
    is(allowed.length, 0, "No allowlist for microphone");
    ok(!ifr.contentDocument.featurePolicy.allowsFeature("vr"), "Vibrate is disabled for self");
    ok(!ifr.contentDocument.featurePolicy.allowsFeature("vr", location.origin), "Vibrate is disabled for self");
    ok(!ifr.contentDocument.featurePolicy.allowsFeature("vr", "https://foo.bar"), "Vibrate is disabled for foo.bar");
    allowed = ifr.contentDocument.featurePolicy.getAllowlistForFeature("vr");
    is(allowed.length, 0, "No allowlist for vr");
    ok(ifr.contentDocument.featurePolicy.allowedFeatures().includes("camera"), "Camera is allowed");
    ok(ifr.contentDocument.featurePolicy.allowedFeatures().includes("geolocation"), "Geolocation is allowed");
    // microphone is disabled for this origin
    ok(!ifr.contentDocument.featurePolicy.allowedFeatures().includes("microphone"), "Microphone is not allowed");
    // vr is disabled everywhere.
    ok(!ifr.contentDocument.featurePolicy.allowedFeatures().includes("vr"), "VR is not allowed");
    next();
  };
  document.body.appendChild(ifr);
}
function test_cross_iframe_without_allow() {
  info("Checking cross HTMLIFrameElement.featurePolicy no allow");
  let ifr = document.getElementById("cross_ifr");
  ok("featurePolicy" in ifr, "HTMLIFrameElement.featurePolicy exists");
  ok(!ifr.featurePolicy.allowsFeature("foobar"), "Random feature");
  ok(ifr.featurePolicy.allowsFeature("camera"), "Camera is allowed for self");
  ok(ifr.featurePolicy.allowsFeature("camera", CROSS_ORIGIN), "Camera is allowed for self");
  ok(!ifr.featurePolicy.allowsFeature("camera", "https://foo.bar"), "Camera is not allowed for a random URL");
  let allowed = ifr.featurePolicy.getAllowlistForFeature("camera");
  is(allowed.length, 1, "Only 1 entry in allowlist for camera");
  is(allowed[0], CROSS_ORIGIN, "allowlist is 'self'");
  ok(!ifr.featurePolicy.allowsFeature("geolocation"), "Geolocation is not allowed for self");
  ok(!ifr.featurePolicy.allowsFeature("geolocation", CROSS_ORIGIN),
    "Geolocation is not allowed for self");
  ok(!ifr.featurePolicy.allowsFeature("geolocation", "https://foo.bar"), "Geolocation is not allowed for any random URL");
  allowed = ifr.featurePolicy.getAllowlistForFeature("geolocation");
  is(allowed.length, 0, "No allowlist for geolocation");
  ok(ifr.featurePolicy.allowsFeature("microphone"), "Microphone is enabled for self");
  ok(ifr.featurePolicy.allowsFeature("microphone", CROSS_ORIGIN), "Microphone is enabled for self");
  ok(!ifr.featurePolicy.allowsFeature("microphone", "https://foo.bar"), "Microphone is disabled for foo.bar");
  ok(!ifr.featurePolicy.allowsFeature("microphone", "https://example.com"), "Microphone is disabled for example.com");
  allowed = ifr.featurePolicy.getAllowlistForFeature("microphone");
  is(allowed.length, 1, "Only 1 entry in allowlist for microphone");
  is(allowed[0], CROSS_ORIGIN, "allowlist is self");
  ok(!ifr.featurePolicy.allowsFeature("vr"), "Vibrate is disabled for self");
  ok(!ifr.featurePolicy.allowsFeature("vr", CROSS_ORIGIN), "Vibrate is disabled for self");
  allowed = ifr.featurePolicy.getAllowlistForFeature("vr");
  is(allowed.length, 0, "No allowlist for vr");
  ok(ifr.featurePolicy.allowedFeatures().includes("camera"), "Camera is allowed");
  ok(!ifr.featurePolicy.allowedFeatures().includes("geolocation"), "Geolocation is not allowed");
  // microphone is enabled for this origin
  ok(ifr.featurePolicy.allowedFeatures().includes("microphone"), "microphone is allowed");
  // vr is disabled everywhere.
  ok(!ifr.featurePolicy.allowedFeatures().includes("vr"), "VR is not allowed");
  next();
}
function test_cross_iframe_with_allow() {
  info("Checking cross HTMLIFrameElement.featurePolicy with allow");
  let ifr = document.getElementById("cross_ifr");
  ok("featurePolicy" in ifr, "HTMLIFrameElement.featurePolicy exists");
  ifr.setAttribute("allow", "geolocation; camera 'none'");
  ok(!ifr.featurePolicy.allowsFeature("foobar"), "Random feature");
  ok(!ifr.featurePolicy.allowsFeature("camera"), "Camera is not allowed");
  let allowed = ifr.featurePolicy.getAllowlistForFeature("camera");
  is(allowed.length, 0, "Camera has an empty allowlist");
  ok(ifr.featurePolicy.allowsFeature("geolocation"), "Geolocation is allowed for self");
  ok(ifr.featurePolicy.allowsFeature("geolocation", CROSS_ORIGIN), "Geolocation is allowed for self");
  ok(!ifr.featurePolicy.allowsFeature("geolocation", "https://foo.bar"), "Geolocation is not allowed for any random URL");
  allowed = ifr.featurePolicy.getAllowlistForFeature("geolocation");
  is(allowed.length, 1, "Only 1 entry in allowlist for geolocation");
  is(allowed[0], CROSS_ORIGIN, "allowlist is '*'");
  ok(ifr.featurePolicy.allowsFeature("microphone"), "Microphone is enabled for self");
  ok(ifr.featurePolicy.allowsFeature("microphone", CROSS_ORIGIN), "Microphone is enabled for self");
  ok(!ifr.featurePolicy.allowsFeature("microphone", "https://foo.bar"), "Microphone is disabled for foo.bar");
  ok(!ifr.featurePolicy.allowsFeature("microphone", "https://example.com"), "Microphone is disabled for example.com");
  allowed = ifr.featurePolicy.getAllowlistForFeature("microphone");
  is(allowed.length, 1, "Only 1 entry in allowlist for microphone");
  is(allowed[0], CROSS_ORIGIN, "allowlist is self");
  ok(!ifr.featurePolicy.allowsFeature("vr"), "Vibrate is disabled for self");
  ok(!ifr.featurePolicy.allowsFeature("vr", CROSS_ORIGIN), "Vibrate is disabled for self");
  allowed = ifr.featurePolicy.getAllowlistForFeature("vr");
  is(allowed.length, 0, "No allowlist for vr");
  ok(ifr.featurePolicy.allowedFeatures().includes("geolocation"), "Geolocation is allowed only for self");
  // microphone is enabled for this origin
  ok(ifr.featurePolicy.allowedFeatures().includes("microphone"), "microphone is allowed");
  next();
}
function test_cross_iframe_contentDocument_no_allow() {
  info("Checking cross iframe document.featurePolicy no allow");
  let ifr = document.createElement("iframe");
  ifr.setAttribute("src", "https://example.org/tests/dom/security/featurePolicy/test/mochitest/empty.html");
  ifr.onload = async function() {
    await SpecialPowers.spawn(ifr, [], () => {
      Assert.ok("featurePolicy" in this.content.document, "We have this.content.document.featurePolicy");
      Assert.ok(!this.content.document.featurePolicy.allowsFeature("foobar"), "Random feature");
      Assert.ok(!this.content.document.featurePolicy.allowsFeature("foobar", "https://www.something.net"), "Random feature");
      Assert.ok(this.content.document.featurePolicy.allowsFeature("camera"), "Camera is allowed for self");
      Assert.ok(this.content.document.featurePolicy.allowsFeature("camera", "https://example.org"), "Camera is allowed for self");
      Assert.ok(!this.content.document.featurePolicy.allowsFeature("camera", "https://foo.bar"), "Camera is not allowed for a random URL");
      let allowed = this.content.document.featurePolicy.getAllowlistForFeature("camera");
      Assert.equal(allowed.length, 1, "Only 1 entry in allowlist for camera");
      Assert.ok(!this.content.document.featurePolicy.allowsFeature("geolocation"), "Geolocation is not allowed for self");
        "Geolocation is not allowed for self");
      Assert.ok(!this.content.document.featurePolicy.allowsFeature("geolocation", "https://foo.bar"), "Geolocation is not allowed for any random URL");
      allowed = this.content.document.featurePolicy.getAllowlistForFeature("geolocation");
      Assert.equal(allowed.length, 0, "No allowlist for geolocation");
      Assert.ok(this.content.document.featurePolicy.allowsFeature("microphone"), "Microphone is enabled for self");
      Assert.ok(this.content.document.featurePolicy.allowsFeature("microphone", "https://example.org"), "Microphone is enabled for self");
      Assert.ok(!this.content.document.featurePolicy.allowsFeature("microphone", "https://foo.bar"), "Microphone is disabled for foo.bar");
      Assert.ok(!this.content.document.featurePolicy.allowsFeature("microphone", "https://example.com"), "Microphone is disabled for example.com");
      allowed = this.content.document.featurePolicy.getAllowlistForFeature("microphone");
      Assert.equal(allowed.length, 1, "Only 1 entry in allowlist for microphone");
      Assert.ok(!this.content.document.featurePolicy.allowsFeature("vr"), "Vibrate is disabled for self");
      Assert.ok(!this.content.document.featurePolicy.allowsFeature("vr", "https://example.org"), "Vibrate is disabled for self");
      Assert.ok(!this.content.document.featurePolicy.allowsFeature("vr", "https://foo.bar"), "Vibrate is disabled for foo.bar");
      allowed = this.content.document.featurePolicy.getAllowlistForFeature("vr");
      Assert.equal(allowed.length, 0, "No allowlist for vr");
      Assert.ok(this.content.document.featurePolicy.allowedFeatures().includes("camera"), "Camera is allowed");
      Assert.ok(!this.content.document.featurePolicy.allowedFeatures().includes("geolocation"), "Geolocation is not allowed");
      // microphone is enabled for this origin
      Assert.ok(this.content.document.featurePolicy.allowedFeatures().includes("microphone"), "microphone is allowed");
      // vr is disabled everywhere.
      Assert.ok(!this.content.document.featurePolicy.allowedFeatures().includes("vr"), "VR is not allowed");
    });
    next();
  };
  document.body.appendChild(ifr);
}
function test_cross_iframe_contentDocument_allow() {
  info("Checking cross iframe document.featurePolicy with allow");
  let ifr = document.createElement("iframe");
  ifr.setAttribute("src", "https://example.org/tests/dom/security/featurePolicy/test/mochitest/empty.html");
  ifr.setAttribute("allow", "geolocation; camera 'none'");
  ifr.onload = async function() {
    await SpecialPowers.spawn(ifr, [], () => {
      Assert.ok("featurePolicy" in this.content.document, "We have this.content.document.featurePolicy");
      Assert.ok(!this.content.document.featurePolicy.allowsFeature("foobar"), "Random feature");
      Assert.ok(!this.content.document.featurePolicy.allowsFeature("foobar", "https://www.something.net"), "Random feature");
      Assert.ok(!this.content.document.featurePolicy.allowsFeature("camera"), "Camera is not allowed");
      let allowed = this.content.document.featurePolicy.getAllowlistForFeature("camera");
      Assert.equal(allowed.length, 0, "Camera has an empty allowlist");
      Assert.ok(this.content.document.featurePolicy.allowsFeature("geolocation"), "Geolocation is allowed for self");
      Assert.ok(this.content.document.featurePolicy.allowsFeature("geolocation", "https://example.org"), "Geolocation is allowed for self");
      Assert.ok(!this.content.document.featurePolicy.allowsFeature("geolocation", "https://foo.bar"), "Geolocation is not allowed for any random URL");
      allowed = this.content.document.featurePolicy.getAllowlistForFeature("geolocation");
      Assert.equal(allowed.length, 1, "Only 1 entry in allowlist for geolocation");
      Assert.ok(this.content.document.featurePolicy.allowsFeature("microphone"), "Microphone is enabled for self");
      Assert.ok(this.content.document.featurePolicy.allowsFeature("microphone", "https://example.org"), "Microphone is enabled for self");
      Assert.ok(!this.content.document.featurePolicy.allowsFeature("microphone", "https://foo.bar"), "Microphone is disabled for foo.bar");
      Assert.ok(!this.content.document.featurePolicy.allowsFeature("microphone", "https://example.com"), "Microphone is disabled for example.com");
      allowed = this.content.document.featurePolicy.getAllowlistForFeature("microphone");
      Assert.equal(allowed.length, 1, "Only 1 entry in allowlist for microphone");
      Assert.ok(!this.content.document.featurePolicy.allowsFeature("vr"), "Vibrate is disabled for self");
      Assert.ok(!this.content.document.featurePolicy.allowsFeature("vr", "https://example.org"), "Vibrate is disabled for self");
      Assert.ok(!this.content.document.featurePolicy.allowsFeature("vr", "https://foo.bar"), "Vibrate is disabled for foo.bar");
      allowed = this.content.document.featurePolicy.getAllowlistForFeature("vr");
      Assert.equal(allowed.length, 0, "No allowlist for vr");
      Assert.ok(this.content.document.featurePolicy.allowedFeatures().includes("geolocation"), "Geolocation is allowed only for self");
      // microphone is enabled for this origin
      Assert.ok(this.content.document.featurePolicy.allowedFeatures().includes("microphone"), "microphone is allowed");
    });
    next();
  };
  document.body.appendChild(ifr);
}
var tests = [
  test_document,
  test_iframe_without_allow,
  test_iframe_with_allow,
  test_iframe_contentDocument,
  test_cross_iframe_without_allow,
  test_cross_iframe_with_allow,
  test_cross_iframe_contentDocument_no_allow,
  test_cross_iframe_contentDocument_allow
];
function next() {
  if (!tests.length) {
    SimpleTest.finish();
    return;
  }
  var test = tests.shift();
  test();
}
next();
</script>
</body>
</html>