Commit cbcda7af authored by Luna Lu's avatar Luna Lu Committed by Commit Bot

Add feature-policy to web-platform-tests

This CL creates a feature-policy directory under wpt/, as well, provides some
framework for testing features with feature policy.

Using the framework, this CL added feature policy tests for payment, and
modified existing feature policy usb tests using the framework introduced.

Bug: 732003
Change-Id: I7d690acfe70b63d4935f6a4c6c43e94da5503827
Reviewed-on: https://chromium-review.googlesource.com/533953Reviewed-by: default avatarIan Clelland <iclelland@chromium.org>
Commit-Queue: Luna Lu <loonybear@chromium.org>
Cr-Commit-Position: refs/heads/master@{#481008}
parent 1775c825
<script>
'use strict';
window.onload = function() {
var supportedInstruments = [ { supportedMethods: [ 'visa' ] } ];
var details = {
total: { label: 'Test', amount: { currency: 'USD', value: '5.00' } }
};
try {
new PaymentRequest(supportedInstruments, details);
parent.postMessage({ enabled: true }, '*');
} catch (e) {
parent.postMessage({ enabled: false }, '*');
}
}
</script>
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
'use strict'; 'use strict';
Promise.resolve().then(() => navigator.usb.getDevices()).then(devices => { Promise.resolve().then(() => navigator.usb.getDevices()).then(devices => {
window.parent.postMessage('#OK', '*'); window.parent.postMessage({ enabled: true }, '*');
}, error => { }, error => {
window.parent.postMessage('#' + error.name, '*'); window.parent.postMessage({ enabled: false }, '*');
}); });
</script> </script>
// Tests whether a feature that is enabled/disabled by feature policy works
// as expected.
// Arguments:
// feature_description: a short string describing what feature is being
// tested. Examples: "usb.GetDevices()", "PaymentRequest()".
// test: test created by testharness. Examples: async_test, promise_test.
// src: URL where a feature's availability is checked. Examples:
// "/feature-policy/resources/feature-policy-payment.html",
// "/feature-policy/resources/feature-policy-usb.html".
// expect_feature_available: a callback(data, feature_description) to
// verify if a feature is avaiable or unavailable as expected.
// The file under the path "src" defines what "data" is sent back as a
// pistMessage. Inside the callback, some tests (e.g., EXPECT_EQ,
// EXPECT_TRUE, etc) are run accordingly to test a feature's
// availability.
// Example: expect_feature_available_default(data, feature_description).
// feature_name: Optional argument, only provided when testing iframe allow
// 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
// allow_attribute: Optional argument, only used for testing fullscreen or
// payment: either "allowfullscreen" or "allowpaymentrequest" is passed.
function test_feature_availability(
feature_description, test, src, expect_feature_available, feature_name,
allow_attribute) {
let frame = document.createElement('iframe');
frame.src = src;
if (typeof feature_name !== 'undefined') {
frame.allow.add(feature_name);
}
if (typeof allow_attribute !== 'undefined') {
frame.setAttribute(allow_attribute, true);
}
window.addEventListener('message', test.step_func(evt => {
if (evt.source === frame.contentWindow) {
expect_feature_available(evt.data, feature_description);
document.body.removeChild(frame);
test.done();
}
}));
document.body.appendChild(frame);
}
// Default helper functions to test a feature's availability:
function expect_feature_available_default(data, feature_description) {
assert_true(data.enabled, feature_description);
}
function expect_feature_unavailable_default(data, feature_description) {
assert_false(data.enabled, feature_description);
}
<!DOCTYPE html>
<body>
<script>
// Automatically redirects the page to a new URL on load.
// Load this document with a URL like:
// "feature-policy/resources/redirect-on-load.html#https://www.example.com/"
window.onload = function () {
document.location = document.location.hash.substring(1);
}
</script>
</body>
<!DOCTYPE html>
<body>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/feature-policy/resources/featurepolicy.js></script>
<script>
'use strict';
var relative_path = '/feature-policy/resources/feature-policy-payment.html';
var base_src = '/feature-policy/resources/redirect-on-load.html#';
var same_origin_src = base_src + relative_path;
var cross_origin_src = base_src + 'https://{{domains[www]}}:{{ports[https][0]}}' +
relative_path;
var header = 'Feature-Policy allow="payment"';
async_test(t => {
test_feature_availability(
'PaymentRequest()', t, same_origin_src,
expect_feature_available_default, 'payment');
}, header + ' allows same-origin relocation.');
async_test(t => {
test_feature_availability(
'PaymentRequest()', t, cross_origin_src,
expect_feature_unavailable_default, 'payment');
}, header + ' disallows cross-origin relocation.');
async_test(t => {
test_feature_availability(
'PaymentRequest()', t, same_origin_src,
expect_feature_available_default, 'payment', 'allowpaymentrequest');
}, header + ' allowpaymentrequest=true allows same-origin relocation.');
async_test(t => {
test_feature_availability(
'PaymentRequest()', t, cross_origin_src,
expect_feature_unavailable_default, 'payment', 'allowpaymentrequest');
}, header + ' allowpaymentrequest=true disallows cross-origin relocation.');
</script>
</body>
<!DOCTYPE html>
<body>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/feature-policy/resources/featurepolicy.js></script>
<script>
'use strict';
var same_origin_src = '/feature-policy/resources/feature-policy-payment.html';
var cross_origin_src = 'https://{{domains[www]}}:{{ports[https][0]}}' +
same_origin_src;
var feature_name = 'Feature policy "payment"';
var header = 'allow="payment" attribute';
async_test(t => {
test_feature_availability(
'PaymentRequest()', t, same_origin_src,
expect_feature_available_default, 'payment');
}, feature_name + ' can be enabled in same-origin iframe using ' + header);
async_test(t => {
test_feature_availability(
'PaymentRequest()', t, cross_origin_src,
expect_feature_available_default, 'payment');
}, feature_name + ' can be enabled in cross-origin iframe using ' + header);
</script>
</body>
<!DOCTYPE html>
<body>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/feature-policy/resources/featurepolicy.js></script>
<script>
'use strict';
var same_origin_src = '/feature-policy/resources/feature-policy-payment.html';
var cross_origin_src = 'https://{{domains[www]}}:{{ports[https][0]}}' +
same_origin_src;
var header = 'Feature-Policy header {"payment" : ["*"]}';
test(() => {
var supportedInstruments = [ { supportedMethods: [ 'visa' ] } ];
var details = {
total: { label: 'Test', amount: { currency: 'USD', value: '5.00' } }
};
try {
new PaymentRequest(supportedInstruments, details);
} catch (e) {
assert_unreached();
}
}, header + ' allows the top-level document.');
async_test(t => {
test_feature_availability('PaymentRequest()', t, same_origin_src,
expect_feature_available_default);
}, header + ' allows same-origin iframes.');
async_test(t => {
test_feature_availability('PaymentRequest()', t, cross_origin_src,
expect_feature_available_default);
}, header + ' allows cross-origin iframes.');
async_test(t => {
test_feature_availability(
'PaymentRequest()', t, same_origin_src,
expect_feature_available_default, undefined, 'allowpaymentrequest');
}, header + ' allowpaymentrequest=true allows same-origin iframes.');
async_test(t => {
test_feature_availability(
'PaymentRequest()', t, cross_origin_src,
expect_feature_available_default, undefined, 'allowpaymentrequest');
}, header + ' allowpaymentrequest=true allows cross-origin iframes.');
</script>
</body>
<!DOCTYPE html>
<body>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/feature-policy/resources/featurepolicy.js></script>
<script>
'use strict';
var same_origin_src = '/feature-policy/resources/feature-policy-payment.html';
var cross_origin_src = 'https://{{domains[www]}}:{{ports[https][0]}}' +
same_origin_src;
var header = 'Default "payment" feature policy ["self"]';
test(() => {
var supportedInstruments = [ { supportedMethods: [ 'visa' ] } ];
var details = {
total: { label: 'Test', amount: { currency: 'USD', value: '5.00' } }
};
try {
new PaymentRequest(supportedInstruments, details);
} catch (e) {
assert_unreached();
}
}, header + ' allows the top-level document.');
async_test(t => {
test_feature_availability('PaymentRequest()', t, same_origin_src,
expect_feature_available_default);
}, header + ' allows same-origin iframes.');
async_test(t => {
test_feature_availability('PaymentRequest()', t, cross_origin_src,
expect_feature_unavailable_default);
}, header + ' disallows cross-origin iframes.');
async_test(t => {
test_feature_availability(
'PaymentRequest()', t, same_origin_src,
expect_feature_available_default, undefined, 'allowpaymentrequest');
}, header + ' allowpaymentrequest=true allows same-origin iframes.');
async_test(t => {
test_feature_availability(
'PaymentRequest()', t, cross_origin_src,
expect_feature_available_default, undefined, 'allowpaymentrequest');
}, header + ' allowpaymentrequest=true allows cross-origin iframes.');
</script>
</body>
<!DOCTYPE html>
<body>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/feature-policy/resources/featurepolicy.js></script>
<script>
'use strict';
var same_origin_src = '/feature-policy/resources/feature-policy-payment.html';
var cross_origin_src = 'https://{{domains[www]}}:{{ports[https][0]}}' +
same_origin_src;
var header = 'Feature-Policy header {"payment" : []}';
test(() => {
var supportedInstruments = [ { supportedMethods: [ 'visa' ] } ];
var details = {
total: { label: 'Test', amount: { currency: 'USD', value: '5.00' } }
};
assert_throws('SecurityError', () => {
new PaymentRequest(supportedInstruments, details);
});
}, header + ' disallows the top-level document.');
async_test(t => {
test_feature_availability('PaymentRequest()', t, same_origin_src,
expect_feature_unavailable_default);
}, header + ' disallows same-origin iframes.');
async_test(t => {
test_feature_availability('PaymentRequest()', t, cross_origin_src,
expect_feature_unavailable_default,);
}, header + ' disallows cross-origin iframes.');
async_test(t => {
test_feature_availability(
'PaymentRequest()', t, same_origin_src,
expect_feature_unavailable_default, undefined, 'allowpaymentrequest');
}, header + ' allowpaymentrequest=true disallows same-origin iframes.');
async_test(t => {
test_feature_availability(
'PaymentRequest()', t, cross_origin_src,
expect_feature_unavailable_default, undefined, 'allowpaymentrequest');
}, header + ' allowpaymentrequest=true disallows cross-origin iframes.');
</script>
</body>
function assert_usb_available_in_iframe(test, origin, expected) {
let frame = document.createElement('iframe');
frame.src = origin + '/webusb/resources/check-availability.html';
window.addEventListener('message', test.step_func(evt => {
if (evt.source == frame.contentWindow) {
assert_equals(evt.data, expected);
document.body.removeChild(frame);
test.done();
}
}));
document.body.appendChild(frame);
}
<!DOCTYPE html>
<body>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/feature-policy/resources/featurepolicy.js></script>
<script>
'use strict';
var relative_path = '/feature-policy/resources/feature-policy-usb.html';
var base_src = '/feature-policy/resources/redirect-on-load.html#';
var same_origin_src = base_src + relative_path;
var cross_origin_src = base_src + 'https://{{domains[www]}}:{{ports[https][0]}}' +
relative_path;
var header = 'Feature-Policy allow="usb"';
async_test(t => {
test_feature_availability(
'usb.getDevices()', t, same_origin_src,
expect_feature_available_default, 'usb');
}, header + ' allows same-origin relocation.');
async_test(t => {
test_feature_availability(
'usb.getDevices()', t, cross_origin_src,
expect_feature_unavailable_default, 'usb');
}, header + ' disallows cross-origin relocation.');
</script>
</body>
...@@ -2,23 +2,25 @@ ...@@ -2,23 +2,25 @@
<body> <body>
<script src=/resources/testharness.js></script> <script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script> <script src=/resources/testharnessreport.js></script>
<script src=/feature-policy/resources/featurepolicy.js></script>
<script> <script>
'use strict'; 'use strict';
var same_origin_src = '/feature-policy/resources/feature-policy-usb.html';
var cross_origin_src = 'https://{{domains[www]}}:{{ports[https][0]}}' +
same_origin_src;
var feature_name = 'Feature policy "usb"';
var header = 'allow="usb" attribute';
async_test(t => { async_test(t => {
let frame = document.createElement('iframe'); test_feature_availability(
frame.src = 'https://{{domains[www]}}:{{ports[https][0]}}/webusb/resources/check-availability.html'; 'usb.getDevices()', t, same_origin_src,
frame.allow = 'usb'; expect_feature_available_default, 'usb');
}, feature_name + ' can be enabled in same-origin iframe using ' + header);
window.addEventListener('message', t.step_func(evt => { async_test(t => {
if (evt.source == frame.contentWindow) { test_feature_availability(
assert_equals(evt.data, '#OK'); 'usb.getDevices()', t, cross_origin_src,
document.body.removeChild(frame); expect_feature_available_default, 'usb');
t.done(); }, feature_name + ' can be enabled in cross-origin iframe using ' + header);
}
}));
document.body.appendChild(frame);
}, 'Feature policy "usb" can be enabled in cross-origin iframes using "allowed" attribute.');
</script> </script>
</body> </body>
...@@ -2,20 +2,26 @@ ...@@ -2,20 +2,26 @@
<body> <body>
<script src=/resources/testharness.js></script> <script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script> <script src=/resources/testharnessreport.js></script>
<script src=resources/featurepolicytest.js></script> <script src=/feature-policy/resources/featurepolicy.js></script>
<script> <script>
'use strict'; 'use strict';
var same_origin_src = '/feature-policy/resources/feature-policy-usb.html';
var cross_origin_src = 'https://{{domains[www]}}:{{ports[https][0]}}' +
same_origin_src;
var header = 'Feature-Policy header {"usb" : ["*"]}';
promise_test( promise_test(
() => navigator.usb.getDevices(), () => navigator.usb.getDevices(),
'Feature-Policy header {"usb": ["*"]} allows the top-level document.'); header + ' allows the top-level document.');
async_test(t => { async_test(t => {
assert_usb_available_in_iframe(t, '', '#OK'); test_feature_availability('usb.getDevices()', t, same_origin_src,
}, 'Feature-Policy header {"usb": ["*"]} allows same-origin iframes.'); expect_feature_available_default);
}, header + ' allows same-origin iframes.');
async_test(t => { async_test(t => {
assert_usb_available_in_iframe(t, 'https://{{domains[www]}}:{{ports[https][0]}}', '#OK'); test_feature_availability('usb.getDevices()', t, cross_origin_src,
}, 'Feature-Policy header {"usb": ["*"]} allows cross-origin iframes.'); expect_feature_available_default);
}, header + ' allows cross-origin iframes.');
</script> </script>
</body> </body>
...@@ -2,20 +2,26 @@ ...@@ -2,20 +2,26 @@
<body> <body>
<script src=/resources/testharness.js></script> <script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script> <script src=/resources/testharnessreport.js></script>
<script src=resources/featurepolicytest.js></script> <script src=/feature-policy/resources/featurepolicy.js></script>
<script> <script>
'use strict'; 'use strict';
var same_origin_src = '/feature-policy/resources/feature-policy-usb.html';
var cross_origin_src = 'https://{{domains[www]}}:{{ports[https][0]}}' +
same_origin_src;
var header = 'Default "usb" feature policy ["self"]';
promise_test( promise_test(
() => navigator.usb.getDevices(), () => navigator.usb.getDevices(),
'Default "usb" feature policy ["self"] allows the top-level document.'); header + ' allows the top-level document.');
async_test(t => { async_test(t => {
assert_usb_available_in_iframe(t, '', '#OK'); test_feature_availability('usb.getDevices()', t, same_origin_src,
}, 'Default "usb" feature policy ["self"] allows same-origin iframes.'); expect_feature_available_default);
}, header + ' allows same-origin iframes.');
async_test(t => { async_test(t => {
assert_usb_available_in_iframe(t, 'https://{{domains[www]}}:{{ports[https][0]}}', '#SecurityError'); test_feature_availability('usb.getDevices()', t, cross_origin_src,
}, 'Default "usb" feature policy ["self"] disallows cross-origin iframes.'); expect_feature_unavailable_default);
}, header + ' disallows cross-origin iframes.');
</script> </script>
</body> </body>
...@@ -2,9 +2,13 @@ ...@@ -2,9 +2,13 @@
<body> <body>
<script src=/resources/testharness.js></script> <script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script> <script src=/resources/testharnessreport.js></script>
<script src=resources/featurepolicytest.js></script> <script src=/feature-policy/resources/featurepolicy.js></script>
<script> <script>
'use strict'; 'use strict';
var same_origin_src = '/feature-policy/resources/feature-policy-usb.html';
var cross_origin_src = 'https://{{domains[www]}}:{{ports[https][0]}}' +
same_origin_src;
var header = 'Feature-Policy header {"usb" : []}';
promise_test(() => { promise_test(() => {
return navigator.usb.getDevices().then(() => { return navigator.usb.getDevices().then(() => {
...@@ -12,14 +16,16 @@ promise_test(() => { ...@@ -12,14 +16,16 @@ promise_test(() => {
}, error => { }, error => {
assert_equals(error.name, 'SecurityError'); assert_equals(error.name, 'SecurityError');
}); });
}, 'Feature-Policy header {"usb": []} disallows the top-level document.'); }, header + ' disallows the top-level document.');
async_test(t => { async_test(t => {
assert_usb_available_in_iframe(t, '', '#SecurityError'); test_feature_availability('usb.getDevices()', t, same_origin_src,
}, 'Feature-Policy header {"usb": []} disallows same-origin iframes.'); expect_feature_unavailable_default);
}, header + ' disallows same-origin iframes.');
async_test(t => { async_test(t => {
assert_usb_available_in_iframe(t, 'https://{{domains[www]}}:{{ports[https][0]}}', '#SecurityError'); test_feature_availability('usb.getDevices()', t, cross_origin_src,
}, 'Feature-Policy header {"usb": []} disallows cross-origin iframes.'); expect_feature_unavailable_default);
}, header + ' disallows cross-origin iframes.');
</script> </script>
</body> </body>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment