summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/permissions
diff options
context:
space:
mode:
Diffstat (limited to 'testing/web-platform/tests/permissions')
-rw-r--r--testing/web-platform/tests/permissions/META.yml4
-rw-r--r--testing/web-platform/tests/permissions/all-permissions.html43
-rw-r--r--testing/web-platform/tests/permissions/feature-policy-permissions-query.html11
-rw-r--r--testing/web-platform/tests/permissions/idlharness.any.js27
-rw-r--r--testing/web-platform/tests/permissions/midi-permission.html35
-rw-r--r--testing/web-platform/tests/permissions/non-fully-active.https.html108
-rw-r--r--testing/web-platform/tests/permissions/permissions-cg.https.html36
-rw-r--r--testing/web-platform/tests/permissions/permissions-garbage-collect.https.html52
-rw-r--r--testing/web-platform/tests/permissions/permissions-query-feature-policy-attribute.https.sub.html75
-rw-r--r--testing/web-platform/tests/permissions/permissionsstatus-name.html15
-rw-r--r--testing/web-platform/tests/permissions/resources/empty.html3
11 files changed, 409 insertions, 0 deletions
diff --git a/testing/web-platform/tests/permissions/META.yml b/testing/web-platform/tests/permissions/META.yml
new file mode 100644
index 0000000000..6a05abee46
--- /dev/null
+++ b/testing/web-platform/tests/permissions/META.yml
@@ -0,0 +1,4 @@
+spec: https://w3c.github.io/permissions/
+suggested_reviewers:
+ - miketaylr
+ - marcoscaceres
diff --git a/testing/web-platform/tests/permissions/all-permissions.html b/testing/web-platform/tests/permissions/all-permissions.html
new file mode 100644
index 0000000000..9ad014bc6e
--- /dev/null
+++ b/testing/web-platform/tests/permissions/all-permissions.html
@@ -0,0 +1,43 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Test all known permissions support</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id="log"></div>
+
+<script>
+ // These are marked "at risk" in the spec...
+ const atRisk = [
+ "accelerometer",
+ "ambient-light-sensor",
+ "background-fetch",
+ "background-sync",
+ "bluetooth",
+ "gyroscope",
+ "magnetometer",
+ "midi",
+ "nfc",
+ "screen-wake-lock",
+ "camera",
+ "display-capture",
+ "microphone",
+ "speaker-selection",
+ "xr-spatial-tracking",
+ ];
+
+ // These are known to be supported by multiple engines...
+ const permissions = [
+ "geolocation",
+ "notifications",
+ "persistent-storage",
+ "push",
+ ]
+
+ for (const name of [...permissions, ...atRisk]) {
+ promise_test(async (test) => {
+ const status = await navigator.permissions.query({ name });
+ assert_true(status instanceof PermissionStatus);
+ //assert_equals(status.name, name, `permission's name should be "${name}"`);
+ }, `Query "${name}" permission`);
+ }
+</script>
diff --git a/testing/web-platform/tests/permissions/feature-policy-permissions-query.html b/testing/web-platform/tests/permissions/feature-policy-permissions-query.html
new file mode 100644
index 0000000000..bd152e973e
--- /dev/null
+++ b/testing/web-platform/tests/permissions/feature-policy-permissions-query.html
@@ -0,0 +1,11 @@
+<script>
+'use strict';
+
+Promise.resolve().then(() => navigator.permissions.query({name:'geolocation'}))
+ .then(permissionStatus => {
+ window.parent.postMessage({ state: permissionStatus.state }, '*');
+}, error => {
+ window.parent.postMessage({ state: null }, '*');
+});
+</script>
+
diff --git a/testing/web-platform/tests/permissions/idlharness.any.js b/testing/web-platform/tests/permissions/idlharness.any.js
new file mode 100644
index 0000000000..ff0a969bad
--- /dev/null
+++ b/testing/web-platform/tests/permissions/idlharness.any.js
@@ -0,0 +1,27 @@
+// META: script=/resources/WebIDLParser.js
+// META: script=/resources/idlharness.js
+
+// https://w3c.github.io/permissions/#idl-index
+
+"use strict";
+
+idl_test(
+ ['permissions'],
+ ['html', 'dom'],
+ async idl_array => {
+ try {
+ self.permissionStatus = await navigator.permissions.query({ name: "geolocation" });
+ } catch (e) {}
+
+ if (self.GLOBAL.isWorker()) {
+ idl_array.add_objects({ WorkerNavigator: ['navigator'] });
+ } else {
+ idl_array.add_objects({ Navigator: ['navigator'] });
+ }
+
+ idl_array.add_objects({
+ Permissions: ['navigator.permissions'],
+ PermissionStatus: ['permissionStatus']
+ });
+ }
+);
diff --git a/testing/web-platform/tests/permissions/midi-permission.html b/testing/web-platform/tests/permissions/midi-permission.html
new file mode 100644
index 0000000000..1d75e1c883
--- /dev/null
+++ b/testing/web-platform/tests/permissions/midi-permission.html
@@ -0,0 +1,35 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Test WebIDL conversion when querying the "midi" permission</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id="log"></div>
+
+<script>
+ promise_test(async (test) => {
+ let calledCount = 0;
+ const status = await navigator.permissions.query({
+ get name() {
+ calledCount++;
+ return "midi";
+ },
+ });
+ assert_true(status instanceof PermissionStatus);
+ assert_equals(status.name, "midi", `permission's name should be "midi"`);
+ //
+ // First call should be from:
+ //
+ // Let rootDesc be the object permissionDesc refers to, converted to an
+ // IDL value of type PermissionDescriptor.
+ //
+ // Second from:
+ //
+ // Let typedDescriptor be the object permissionDesc refers to,
+ // converted to an IDL value of rootDesc's name's permission descriptor
+ // type.
+ //
+ // See: https://w3c.github.io/permissions/#query-method
+ //
+ assert_equals(calledCount, 2, "midi permission should be converted twice");
+ }, `querying the "midi" permission requires two WebIDL conversions`);
+</script>
diff --git a/testing/web-platform/tests/permissions/non-fully-active.https.html b/testing/web-platform/tests/permissions/non-fully-active.https.html
new file mode 100644
index 0000000000..1c11afa3d9
--- /dev/null
+++ b/testing/web-platform/tests/permissions/non-fully-active.https.html
@@ -0,0 +1,108 @@
+<!DOCTYPE html>
+<meta charset="utf-8" />
+<title>Geolocation Test: non-fully active document</title>
+<link rel="help" href="https://github.com/w3c/permissions/pull/365" />
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<body></body>
+<script>
+ // Creates the iframe, wait for it to load...
+ async function attachIframe() {
+ const iframe = document.createElement("iframe");
+ await new Promise((resolve) => {
+ iframe.src = "resources/empty.html";
+ iframe.addEventListener("load", resolve, { once: true });
+ document.body.appendChild(iframe);
+ });
+ return iframe;
+ }
+
+ promise_test(async (t) => {
+ const iframe = await attachIframe();
+
+ // Steal the needed references
+ const { permissions } = iframe.contentWindow.navigator;
+ const TypeErrorCtor = iframe.contentWindow.TypeError;
+ const DOMExceptionCtor = iframe.contentWindow.DOMException;
+
+ // Let's check that ordering is correct.
+ await promise_rejects_js(
+ t,
+ TypeErrorCtor,
+ permissions.query({ name: "xxxxx-not-supported" }),
+ "query() should reject if the feature is not supported"
+ );
+
+ // no longer fully active, let's try that again...
+ iframe.remove();
+
+ // Now, let's try with Geolocation as it's supported by all browsers.
+ await promise_rejects_dom(
+ t,
+ "InvalidStateError",
+ DOMExceptionCtor,
+ permissions.query({ name: "whatever" }),
+ "must reject in the right global when the document is not fully active"
+ );
+
+ // Re-attach, and go back to fully active.
+ document.body.appendChild(iframe);
+ await new Promise((resolve) =>
+ iframe.addEventListener("load", resolve, { once: true })
+ );
+
+ // And we are back to fully active, so this should not reject.
+ const status = await iframe.contentWindow.navigator.permissions.query({
+ name: "geolocation",
+ });
+ assert_equals(status.name, "geolocation");
+ iframe.remove();
+ }, "Trying to query() a non-fully active document rejects with a InvalidStateError");
+
+ promise_test(async (t) => {
+ // Create the iframe, wait for it to load...
+ const iframe = await attachIframe();
+
+ // Get the status
+ const initialStatus =
+ await iframe.contentWindow.navigator.permissions.query({
+ name: "geolocation",
+ });
+
+ assert_true("onchange" in initialStatus, "onchange is supported");
+
+ // Let's check events are firing...
+ await new Promise(async (resolve) => {
+ const newState = initialStatus.state === "prompt" ? "denied" : "granted";
+ initialStatus.addEventListener("change", resolve, { once: true });
+ await test_driver.set_permission({ name: "geolocation" }, newState);
+ });
+
+ // No longer fully active...
+ iframe.remove();
+
+ await new Promise(async (resolve, reject) => {
+ // Gets dropped on the floor.
+ initialStatus.addEventListener("change", reject, { once: true });
+ await test_driver.set_permission({ name: "geolocation" }, "prompt");
+ // Try to force it synthetically. This would trigger the event synchronously.
+ initialStatus.dispatchEvent(new Event("change"));
+ resolve();
+ });
+
+ // Re-attach, and go back to fully active.
+ document.body.appendChild(iframe);
+ await new Promise((resolve) =>
+ iframe.addEventListener("load", resolve, { once: true })
+ );
+
+ // Finally, let's recheck that permission state.
+ const finalStatus = await iframe.contentWindow.navigator.permissions.query({
+ name: "geolocation",
+ });
+ assert_equals(finalStatus.state, "prompt", "expected prompt state");
+ iframe.remove();
+ }, "Permission change events shouldn't fire on non-fully active document");
+</script>
diff --git a/testing/web-platform/tests/permissions/permissions-cg.https.html b/testing/web-platform/tests/permissions/permissions-cg.https.html
new file mode 100644
index 0000000000..7a2d8dcbb4
--- /dev/null
+++ b/testing/web-platform/tests/permissions/permissions-cg.https.html
@@ -0,0 +1,36 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Test PermissionStatus's name attribute.</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<script src="/common/gc.js"></script>
+
+<script>
+promise_test(async () => {
+ const { state: initialState } = await navigator.permissions.query({
+ name: "geolocation",
+ });
+
+ const pass = new Promise(async (resolve) => {
+ let status = await navigator.permissions.query({
+ name: "geolocation",
+ });
+ status.addEventListener("change", resolve, { once: true });
+
+ status = null;
+ await garbageCollect();
+
+ // Will cause change event to be dispatched.
+ await test_driver.set_permission({ name: "geolocation" }, "granted");
+ });
+
+ // Wait for the change event to be dispatched.
+ await pass;
+
+ // Reset the permission to its default value.
+ await test_driver.set_permission({ name: "geolocation" }, initialState);
+}, "status is not garbage collected when it goes out of scope");
+
+</script>
diff --git a/testing/web-platform/tests/permissions/permissions-garbage-collect.https.html b/testing/web-platform/tests/permissions/permissions-garbage-collect.https.html
new file mode 100644
index 0000000000..cd650dc8f2
--- /dev/null
+++ b/testing/web-platform/tests/permissions/permissions-garbage-collect.https.html
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<meta charset="utf-8" />
+<title>Test Permission garbage collection persistance.</title>
+<link rel="help" href="https://github.com/w3c/permissions/pull/256" />
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<body>
+ <script>
+ async function createABunchOfGarbage() {
+ const promises = [];
+ for (let i = 0; i < 25; i++) {
+ const promise = new Promise((r) => {
+ const iframe = document.createElement("iframe");
+ iframe.onload = () => r(iframe);
+ iframe.src = "about:blank";
+ document.body.appendChild(iframe);
+ });
+ promises.push(promise);
+ }
+ const iframes = await Promise.all(promises);
+ iframes.forEach((iframe) => iframe.remove());
+ }
+
+ promise_test(async (t) => {
+ t.add_cleanup(() => {
+ return test_driver.set_permission({ name: "geolocation" }, "prompt");
+ });
+
+ const eventPromise = new Promise(
+ async (r) => {
+ // we create the status here, but it goes out of scope
+ // at the end of the function. Thus, we assume it will be
+ // garbage collected.
+ const status = await navigator.permissions.query({
+ name: "geolocation",
+ });
+ status.addEventListener("change", r);
+ },
+ { once: true }
+ );
+
+ // Maybe got garbage collected.
+ await createABunchOfGarbage();
+
+ // Causes event to fire.
+ await test_driver.set_permission({ name: "geolocation" }, "granted");
+ await eventPromise;
+ }, "Events fire even if the status object is garbage collected");
+ </script>
+</body>
diff --git a/testing/web-platform/tests/permissions/permissions-query-feature-policy-attribute.https.sub.html b/testing/web-platform/tests/permissions/permissions-query-feature-policy-attribute.https.sub.html
new file mode 100644
index 0000000000..1d7333d9b5
--- /dev/null
+++ b/testing/web-platform/tests/permissions/permissions-query-feature-policy-attribute.https.sub.html
@@ -0,0 +1,75 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Test permissions query againts feature policy allow attribute</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id="log"></div>
+
+<script>
+ "use strict";
+
+ function test_permissions_query(
+ feature_description, test, src, expect_state, allow_attribute) {
+ let frame = document.createElement('iframe');
+ frame.src = src;
+
+ if (typeof allow_attribute !== 'undefined') {
+ frame.allow = allow_attribute;
+ }
+
+ window.addEventListener('message', test.step_func(function handler(evt) {
+ if (evt.source === frame.contentWindow) {
+ assert_equals(evt.data.state, expect_state, feature_description);
+ document.body.removeChild(frame);
+ window.removeEventListener('message', handler);
+ test.done();
+ }
+ }));
+
+ document.body.appendChild(frame);
+ }
+
+ const same_origin_src =
+ "/permissions/feature-policy-permissions-query.html";
+ const cross_origin_src =
+ "https://{{domains[www]}}:{{ports[https][0]}}" + same_origin_src;
+
+ async_test(t => {
+ test_permissions_query(
+ 'navigator.permissions.query("geolocation")',
+ t,
+ same_origin_src,
+ "prompt",
+ "geolocation"
+ );
+ }, 'Permissions.state is "prompt" with allow="geolocation" in same-origin iframes.');
+
+ async_test(t => {
+ test_permissions_query(
+ 'navigator.permissions.query("geolocation")',
+ t,
+ cross_origin_src,
+ "prompt",
+ "geolocation"
+ );
+ }, 'Permissions.state is "prompt" with allow="geolocation" in cross-origin iframes.');
+
+ async_test(t => {
+ test_permissions_query(
+ 'navigator.permissions.query("geolocation")',
+ t,
+ same_origin_src,
+ "prompt"
+ );
+ }, 'Permission.state is "prompt" in same-origin iframes.');
+
+ async_test(t => {
+ test_permissions_query(
+ 'navigator.permissions.query("geolocation")',
+ t,
+ cross_origin_src,
+ "denied"
+ );
+ }, 'Permission.state is "denied" in cross-origin iframes.');
+
+</script>
diff --git a/testing/web-platform/tests/permissions/permissionsstatus-name.html b/testing/web-platform/tests/permissions/permissionsstatus-name.html
new file mode 100644
index 0000000000..db1d1bb83e
--- /dev/null
+++ b/testing/web-platform/tests/permissions/permissionsstatus-name.html
@@ -0,0 +1,15 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Test PermissionStatus's name attribute.</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id="log"></div>
+
+<script>
+promise_test(async () => {
+ const result = await navigator.permissions.query({
+ name: "geolocation",
+ });
+ assert_equals(result.name, "geolocation", "Name was geolocation");
+});
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/permissions/resources/empty.html b/testing/web-platform/tests/permissions/resources/empty.html
new file mode 100644
index 0000000000..b0653f8c0c
--- /dev/null
+++ b/testing/web-platform/tests/permissions/resources/empty.html
@@ -0,0 +1,3 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Just a support file</title>