Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/feature-policy/resources/featurepolicy.js (260081 => 260082)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/feature-policy/resources/featurepolicy.js 2020-04-14 18:07:24 UTC (rev 260081)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/feature-policy/resources/featurepolicy.js 2020-04-14 18:42:40 UTC (rev 260082)
@@ -1,3 +1,8 @@
+// Feature test to avoid timeouts
+function assert_feature_policy_supported() {
+ assert_not_equals(document.featurePolicy, undefined,
+ 'Feature Policy is supported');
+}
// Tests whether a feature that is enabled/disabled by feature policy works
// as expected.
// Arguments:
@@ -18,7 +23,7 @@
// attribute. "feature_name" is the feature name of a policy controlled
// feature (https://wicg.github.io/feature-policy/#features).
// See examples at:
-// https://github.com/WICG/feature-policy/blob/gh-pages/features.md
+// https://github.com/WICG/feature-policy/blob/master/features.md
// allow_attribute: Optional argument, only used for testing fullscreen or
// payment: either "allowfullscreen" or "allowpaymentrequest" is passed.
function test_feature_availability(
@@ -78,7 +83,7 @@
// tests the feature availability and posts the result back to the parent.
// Otherwise, does nothing.
function test_feature_in_iframe(feature_name, feature_promise_factory) {
- if (location.hash.includes(feature_name)) {
+ if (location.hash.endsWith(`#${feature_name}`)) {
feature_promise_factory().then(
() => window.parent.postMessage('#OK', '*'),
(e) => window.parent.postMessage('#' + e.name, '*'));
@@ -246,4 +251,208 @@
},
'Feature policy "' + feature_name +
'" can be disabled in cross-origin iframes using "allow" attribute.');
+
+ // 5. Blocked in same-origin iframe with "allow" attribute set to 'none'.
+ async_test(
+ t => {
+ test_feature_availability_with_post_message_result(
+ t, same_origin_frame_pathname, '#' + error_name,
+ feature_name + " 'none'");
+ },
+ 'Feature policy "' + feature_name +
+ '" can be disabled in same-origin iframes using "allow" attribute.');
}
+
+// This function tests that a given policy allows each feature for the correct
+// list of origins specified by the |expected_policy|.
+// Arguments:
+// expected_policy: A list of {feature, allowlist} pairs where the feature is
+// enabled for every origin in the allowlist, in the |policy|.
+// policy: Either a document.featurePolicy or an iframe.featurePolicy to be
+// tested.
+// message: A short description of what policy is being tested.
+function test_allowlists(expected_policy, policy, message) {
+ for (var allowlist of allowlists) {
+ test(function() {
+ assert_array_equals(
+ policy.getAllowlistForFeature(allowlist.feature),
+ allowlist.allowlist);
+ }, message + ' for feature ' + allowlist.feature);
+ }
+}
+
+// This function tests that a subframe's document policy allows a given feature.
+// A feature is allowed in a frame either through inherited policy or specified
+// by iframe allow attribute.
+// Arguments:
+// test: test created by testharness. Examples: async_test, promise_test.
+// feature: feature name that should be allowed in the frame.
+// src: the URL to load in the frame.
+// allow: the allow attribute (container policy) of the iframe
+function test_allowed_feature_for_subframe(message, feature, src, allow) {
+ let frame = document.createElement('iframe');
+ if (typeof allow !== 'undefined') {
+ frame.allow = allow;
+ }
+ promise_test(function() {
+ assert_feature_policy_supported();
+ frame.src = ""
+ return new Promise(function(resolve, reject) {
+ window.addEventListener('message', function handler(evt) {
+ resolve(evt.data);
+ }, { once: true });
+ document.body.appendChild(frame);
+ }).then(function(data) {
+ assert_true(data.includes(feature), feature);
+ });
+ }, message);
+}
+
+// This function tests that a subframe's document policy disallows a given
+// feature. A feature is allowed in a frame either through inherited policy or
+// specified by iframe allow attribute.
+// Arguments:
+// test: test created by testharness. Examples: async_test, promise_test.
+// feature: feature name that should not be allowed in the frame.
+// src: the URL to load in the frame.
+// allow: the allow attribute (container policy) of the iframe
+function test_disallowed_feature_for_subframe(message, feature, src, allow) {
+ let frame = document.createElement('iframe');
+ if (typeof allow !== 'undefined') {
+ frame.allow = allow;
+ }
+ promise_test(function() {
+ assert_feature_policy_supported();
+ frame.src = ""
+ return new Promise(function(resolve, reject) {
+ window.addEventListener('message', function handler(evt) {
+ resolve(evt.data);
+ }, { once: true });
+ document.body.appendChild(frame);
+ }).then(function(data) {
+ assert_false(data.includes(feature), feature);
+ });
+ }, message);
+}
+
+// This function tests that a subframe with header policy defined on a given
+// feature allows and disallows the feature as expected.
+// Arguments:
+// feature: feature name.
+// frame_header_policy: either *, 'self' or 'none', defines the frame
+// document's header policy on |feature|.
+// src: the URL to load in the frame.
+// test_expects: contains 6 expected results of either |feature| is allowed
+// or not inside of a local or remote iframe nested inside
+// the subframe given the header policy to be either *,
+// 'slef', or 'none'.
+// test_name: name of the test.
+function test_subframe_header_policy(
+ feature, frame_header_policy, src, test_expects, test_name) {
+ let frame = document.createElement('iframe');
+ promise_test(function() {
+ assert_feature_policy_supported()
+ frame.src = "" + '?pipe=sub|header(Feature-Policy,' + feature + ' '
+ + frame_header_policy + ';)';
+ return new Promise(function(resolve, reject) {
+ let results = [];
+ window.addEventListener('message', function handler(evt) {
+ results.push(evt.data);
+ if (results.length >= 6) {
+ resolve(results);
+ }
+ });
+ document.body.appendChild(frame);
+ }).then(function(results) {
+ for (var j = 0; j < results.length; j++) {
+ var data = ""
+
+ function test_result(message, test_expect) {
+ if (test_expect) {
+ assert_true(data.allowedfeatures.includes(feature), message);
+ } else {
+ assert_false(data.allowedfeatures.includes(feature), message);
+ }
+ }
+
+ if (data.frame === 'local') {
+ if (data.policy === '*') {
+ test_result('local_all:', test_expects.local_all);
+ }
+ if (data.policy === '\'self\'') {
+ test_result('local_self:', test_expects.local_self);
+ }
+ if (data.policy === '\'none\'') {
+ test_result('local_none:', test_expects.local_none);
+ }
+ }
+
+ if (data.frame === 'remote') {
+ if (data.policy === '*') {
+ test_result('remote_all:', test_expects.remote_all);
+ }
+ if (data.policy === '\'self\'') {
+ test_result('remote_self:', test_expects.remote_self);
+ }
+ if (data.policy === '\'none\'') {
+ test_result('remote_none:', test_expects.remote_none);
+ }
+ }
+ }
+ });
+ }, test_name);
+}
+
+// This function tests that frame policy allows a given feature correctly. A
+// feature is allowed in a frame either through inherited policy or specified
+// by iframe allow attribute.
+// Arguments:
+// feature: feature name.
+// src: the URL to load in the frame. If undefined, the iframe will have a
+// srcdoc="" attribute
+// test_expect: boolean value of whether the feature should be allowed.
+// allow: optional, the allow attribute (container policy) of the iframe.
+// allowfullscreen: optional, boolean value of allowfullscreen attribute.
+// sandbox: optional boolean. If true, the frame will be sandboxed (with
+// allow-scripts, so that tests can run in it.)
+function test_frame_policy(
+ feature, src, srcdoc, test_expect, allow, allowfullscreen, sandbox) {
+ let frame = document.createElement('iframe');
+ document.body.appendChild(frame);
+ // frame_policy should be dynamically updated as allow and allowfullscreen is
+ // updated.
+ var frame_policy = frame.featurePolicy;
+ if (typeof allow !== 'undefined') {
+ frame.setAttribute('allow', allow);
+ }
+ if (!!allowfullscreen) {
+ frame.setAttribute('allowfullscreen', true);
+ }
+ if (!!sandbox) {
+ frame.setAttribute('sandbox', 'allow-scripts');
+ }
+ if (!!src) {
+ frame.src = ""
+ }
+ if (!!srcdoc) {
+ frame.srcdoc = "<h1>Hello world!</h1>";
+ }
+ if (test_expect) {
+ assert_true(frame_policy.allowedFeatures().includes(feature));
+ } else {
+ assert_false(frame_policy.allowedFeatures().includes(feature));
+ }
+}
+
+function expect_reports(report_count, policy_name, description) {
+ async_test(t => {
+ var num_received_reports = 0;
+ new ReportingObserver(t.step_func((reports, observer) => {
+ const relevant_reports = reports.filter(r => (r.body.featureId === policy_name));
+ num_received_reports += relevant_reports.length;
+ if (num_received_reports >= report_count) {
+ t.done();
+ }
+ }), {types: ['feature-policy-violation'], buffered: true}).observe();
+ }, description);
+}