Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion LayoutTests/TestExpectations
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,10 @@ http/wpt/webauthn/public-key-credential-get-failure.https.html [ DumpJSConsoleLo
imported/w3c/web-platform-tests/FileAPI/url/sandboxed-iframe.html [ DumpJSConsoleLogInStdErr ]
imported/w3c/web-platform-tests/WebIDL/current-realm.html [ DumpJSConsoleLogInStdErr ]
imported/w3c/web-platform-tests/eventsource/format-mime-bogus.any.html [ DumpJSConsoleLogInStdErr ]
imported/w3c/web-platform-tests/feature-policy/feature-policy-frame-policy-allowed-for-all.https.sub.html [ DumpJSConsoleLogInStdErr ]
imported/w3c/web-platform-tests/feature-policy/feature-policy-frame-policy-allowed-for-self.https.sub.html [ DumpJSConsoleLogInStdErr ]
imported/w3c/web-platform-tests/feature-policy/feature-policy-frame-policy-allowed-for-some.https.sub.html [ DumpJSConsoleLogInStdErr ]
imported/w3c/web-platform-tests/feature-policy/feature-policy-frame-policy-disallowed-for-all.https.sub.html [ DumpJSConsoleLogInStdErr ]
imported/w3c/web-platform-tests/html/anonymous-iframe/embedding.tentative.https.window.html [ DumpJSConsoleLogInStdErr ]
imported/w3c/web-platform-tests/html/browsers/browsing-the-web/navigating-across-documents/failure-check-sequence.https.html [ DumpJSConsoleLogInStdErr ]
imported/w3c/web-platform-tests/html/browsers/browsing-the-web/navigating-across-documents/redirect-to-data.html [ DumpJSConsoleLogInStdErr ]
Expand Down Expand Up @@ -567,7 +571,6 @@ imported/w3c/web-platform-tests/clipboard-apis/feature-policy/clipboard-read/cli
imported/w3c/web-platform-tests/clipboard-apis/feature-policy/clipboard-read/clipboard-read-enabled-by-feature-policy-cross-origin-tentative.https.sub.html [ Skip ]
imported/w3c/web-platform-tests/clipboard-apis/feature-policy/clipboard-read/clipboard-read-enabled-by-feature-policy.tentative.https.sub.html [ Skip ]
imported/w3c/web-platform-tests/clipboard-apis/feature-policy/clipboard-read/clipboard-read-enabled-on-self-origin-by-feature-policy.tentative.https.sub.html [ Skip ]

imported/w3c/web-platform-tests/cookies/domain/domain-attribute-host-with-and-without-leading-period.sub.https.html [ Skip ]
imported/w3c/web-platform-tests/cookies/domain/domain-attribute-host-with-leading-period.sub.https.html [ Skip ]
imported/w3c/web-platform-tests/cookies/domain/domain-attribute-matches-host.sub.https.html [ Skip ]
Expand All @@ -587,6 +590,22 @@ imported/w3c/web-platform-tests/eventsource/eventsource-request-cancellation.any
imported/w3c/web-platform-tests/eventsource/request-cache-control.any.html [ Skip ]
imported/w3c/web-platform-tests/eventsource/request-cache-control.any.worker.html [ Skip ]
imported/w3c/web-platform-tests/eventsource/request-credentials.any.window.html [ Skip ]
imported/w3c/web-platform-tests/feature-policy/experimental-features/focus-without-user-activation-enabled-tentative.sub.html [ Skip ]
imported/w3c/web-platform-tests/feature-policy/experimental-features/trust-token-redemption-default-feature-policy.tentative.https.sub.html [ Skip ]
imported/w3c/web-platform-tests/feature-policy/experimental-features/vertical-scroll-disabled-scrollbar-tentative.html [ Skip ]
imported/w3c/web-platform-tests/feature-policy/payment-allowed-by-feature-policy-attribute-redirect-on-load.https.sub.html [ Skip ]
imported/w3c/web-platform-tests/feature-policy/payment-allowed-by-feature-policy-attribute.https.sub.html [ Skip ]
imported/w3c/web-platform-tests/feature-policy/payment-allowed-by-feature-policy.https.sub.html [ Skip ]
imported/w3c/web-platform-tests/feature-policy/payment-default-feature-policy.https.sub.html [ Skip ]
imported/w3c/web-platform-tests/feature-policy/payment-disabled-by-feature-policy.https.sub.html [ Skip ]
imported/w3c/web-platform-tests/feature-policy/picture-in-picture-allowed-by-feature-policy-attribute-redirect-on-load.https.sub.html [ Skip ]
imported/w3c/web-platform-tests/feature-policy/picture-in-picture-allowed-by-feature-policy-attribute.https.sub.html [ Skip ]
imported/w3c/web-platform-tests/feature-policy/picture-in-picture-allowed-by-feature-policy.https.sub.html [ Skip ]
imported/w3c/web-platform-tests/feature-policy/picture-in-picture-default-feature-policy.https.sub.html [ Skip ]
imported/w3c/web-platform-tests/feature-policy/picture-in-picture-disabled-by-feature-policy.https.sub.html [ Skip ]
imported/w3c/web-platform-tests/feature-policy/policy-extends-to-sandbox.html [ Skip ]
imported/w3c/web-platform-tests/feature-policy/reporting/geolocation-reporting.https.html [ Skip ]
imported/w3c/web-platform-tests/feature-policy/reporting/screen-wake-lock-reporting.https.html [ Skip ]
imported/w3c/web-platform-tests/geolocation-API/non-secure-contexts.http.html [ Skip ]
imported/w3c/web-platform-tests/geolocation-API/getCurrentPosition_permission_allow.https.html [ Skip ]
imported/w3c/web-platform-tests/geolocation-API/getCurrentPosition_permission_deny.https.html [ Skip ]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@
"web-platform-tests/entries-api": "import",
"web-platform-tests/eventsource": "import",
"web-platform-tests/ext-xhtml-pubid": "skip",
"web-platform-tests/feature-policy": "skip",
"web-platform-tests/feature-policy": "import",
"web-platform-tests/feature-policy/resources": "import",
"web-platform-tests/feature-policy/resources/": "import",
"web-platform-tests/fetch": "import",
Expand Down
1 change: 1 addition & 0 deletions LayoutTests/imported/w3c/resources/resource-files.json
Original file line number Diff line number Diff line change
Expand Up @@ -3080,6 +3080,7 @@
"web-platform-tests/encoding/legacy-mb-tchinese/big5/big5_chars_extra.html",
"web-platform-tests/encoding/legacy-mb-tchinese/big5/big5_errors.html",
"web-platform-tests/eventsource/eventsource-onmessage-realm-support.htm",
"web-platform-tests/feature-policy/feature-policy-frame-policy-timing-iframe-camera.https.sub.html",
"web-platform-tests/fetch/api/request/multi-globals/current/current.html",
"web-platform-tests/fetch/api/request/multi-globals/incumbent/incumbent.html",
"web-platform-tests/fetch/api/response/multi-globals/current/current.html",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@


Harness Error (TIMEOUT), message = null

FAIL Feature-Policy header clipboard-write "none" disallows the top-level document. promise_test: Unhandled rejection with value: object "Error: unimplemented"
TIMEOUT Feature-Policy header clipboard-write "none" disallows same-origin iframes. Test timed out
TIMEOUT Feature-Policy header clipboard-write "none" disallows cross-origin iframes. Test timed out
PASS Feature-Policy header clipboard-write "none" disallows same-origin iframes.
PASS Feature-Policy header clipboard-write "none" disallows cross-origin iframes.

Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
spec: https://wicg.github.io/feature-policy/
suggested_reviewers:
- bakulf
- clelland
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Feature Policy Guide
## How to Test a New Feature with Feature Policy

This directory contains a framework to test features with feature policy.

When adding a new feature to feature policy, the following cases should be tested:
* feature enabled by header policy [HTTP tests]
+ test when feature is enabled by feature policy HTTP header;
* feature disabled by header policy [HTTP tests]
+ test when feature is disabled by feature policy HTTP header;
* feature enabled on self origin by header policy [HTTP tests]
+ test when feature is enabled only on self origin by feature policy HTTP
header.
* feature allowed by container policy (iframe "allow" attribute);
+ test when feature is enabled by iframe "allow" attribute on self and cross
origins.
* feature allowed by container policy, redirect on load.
+ test when feature is enabled by iframe "allow" attribute when the iframe
is being redirected to a new origin upon loading

### How to Use the Test Framework
Use `test_feature_availability()` defined in
`/feature-policy/resources/featurepolicy.js`. Please refer to the comments
in `/feature-policy/resources/featurepolicy.js` for how this function works.

### How to Write Header Policy Tests
HTTP tests are used to test features with header policy.

* Define the header policy in `<feature-name>-<enabled | disabled | enabled-on-self-origin>-by-feature-policy.https.sub.html.headers`. Example:

Feature-Policy: feature-name *


* In `<feature-name>-<enabled | disabled | enabled-on-self-origin>-by-feature-policy.https.sub.html`:
* test if feature is enabled / disabled in the main frame;
* test if feature is enabled / disabled in a same-origin iframe;
* test if feature is enabled / disabled in a cross-origin iframe.

Examples:
`/feature-policy/payment-disabled-by-feature-policy.https.sub.html`
`/feature-policy/payment-disabled-by-feature-policy.https.sub.html.headers`

### How to Write Container Policy Tests
Simply use `test_feature_availability()` with the optional argument
`feature_name` specified to test if:
* feature is enabled / disabled in a same-origin iframe;
* feature is enabled / disabled in a cross-origin iframe.

Example:
`/feature-policy/payment-allowed-by-feature-policy-attribute.https.sub.html`

### How to Write Container Policy Tests with Redirect
Similar to the section above, append
`/feature-policy/resources/redirect-on-load.html#` to the argument `src`
passed to `test_feature_availability()`.

Example:
`/feature-policy/payment-allowed-by-feature-policy-attribute-redirect-on-load.https.sub.html`

Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@


FAIL When the policy is disabled, 'autofocus' and scripted focus do not focus the document. assert_false: 'autofocus' should not work. expected false got true

Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="./resources/common.js"></script>
<title> 'focus-without-user-activation' Policy : Correctly block automatic focus when policy disabled
</title>
<body>
<script>
"use strict"
// Note: According to html spec: https://html.spec.whatwg.org/#attr-fe-autofocus,
// topDocument's autofocus processed flag initially is false and is set to true
// after flushing autofocus candidates, i.e. flush of autofocus candidates
// only happens once per page load.
// In order to test the behaviour with both focus-without-user-activation on and off:
// two test files are necessary:
// - focus-without-user-activation-disabled-tentative.html
// - focus-without-user-activation-enabled-tentative.sub.html

// Use same origin url here because when iframe document has cross origin
// url, autofocus will be blocked by default with following console error:
// "Blocked autofocusing on a form control in a cross-origin subframe."
const url = "/feature-policy/experimental-features/resources/focus-without-user-activation-iframe-tentative.html";

function subframe_focused(subframe, event_name, timeout) {
return new Promise(resolve => {
window.onmessage = m => resolve(m.data.focused);
subframe.contentWindow.postMessage({
event: event_name,
timeout: timeout
}, "*");
});
}

promise_test( async (instance) => {
const frame = createIframe(document.body, {
sandbox: "allow-scripts allow-same-origin",
allow: "focus-without-user-activation 'none'",
src: url
});

await wait_for_load(frame);
assert_false(await subframe_focused(frame, "autofocus", 400), "'autofocus' should not work.");
window.focus(); // Reset focus state in subframe.
assert_false(await subframe_focused(frame, "focus-input", 400), "'element.focus' should not work.");
window.focus(); // Reset focus state in subframe.
assert_false(await subframe_focused(frame, "focus-window", 400), "'window.focus' should not work.");
window.focus(); // Reset focus state in subframe.
}, "When the policy is disabled, 'autofocus' and scripted focus do not focus " +
"the document.");
</script>
</body>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@


Harness Error (TIMEOUT), message = null

TIMEOUT When the policy is enabled, 'autofocus' and scripted focus do focus the document. Test timed out

Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="./resources/common.js"></script>
<title> 'focus-without-user-activation' Policy : Correctly block automatic focus when policy disabled
</title>
<body>
<script>
"use strict"
// Note: According to html spec: https://html.spec.whatwg.org/#attr-fe-autofocus,
// topDocument's autofocus processed flag initially is false and is set to true
// after flushing autofocus candidates, i.e. flush of autofocus candidates
// only happens once per page load.
// In order to test the behaviour with both focus-without-user-activation on and off:
// two test files are necessary:
// - focus-without-user-activation-disabled-tentative.html
// - focus-without-user-activation-enabled-tentative.sub.html

// Cross origin subframe should not be able to use autofocus to steal focus
// from main frame by default. However, with focus-without-user-activation
// enabled for subframe, subframe should be able to autofocus.
const url = "http://{{hosts[alt][www1]}}:{{ports[http][0]}}/feature-policy/experimental-features/resources/focus-without-user-activation-iframe-tentative.html";

function subframe_focused(subframe, event_name, timeout) {
return new Promise(resolve => {
window.onmessage = m => resolve(m.data.focused);
subframe.contentWindow.postMessage({
event: event_name,
timeout: timeout
}, "*");
});
}

promise_test( async (instance) => {
const frame = createIframe(document.body, {
sandbox: "allow-scripts allow-same-origin",
allow: "focus-without-user-activation *",
src: url
});

await wait_for_load(frame);
assert_true(await subframe_focused(frame, "autofocus"), "'autofocus' should work.");
window.focus(); // Reset focus state in subframe.
assert_true(await subframe_focused(frame, "focus-input"), "'element.focus' should work.");
window.focus(); // Reset focus state in subframe.
assert_true(await subframe_focused(frame, "focus-window"), "'window.focus' should work.");
window.focus(); // Reset focus state in subframe.
}, "When the policy is enabled, 'autofocus' and scripted focus do focus " +
"the document.");
</script>
</body>
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
const url_base = "/feature-policy/experimental-features/resources/";
window.messageResponseCallback = null;

function setFeatureState(iframe, feature, origins) {
iframe.setAttribute("allow", `${feature} ${origins};`);
}

// Returns a promise which is resolved when the <iframe> is navigated to |url|
// and "load" handler has been called.
function loadUrlInIframe(iframe, url) {
return new Promise((resolve) => {
iframe.addEventListener("load", resolve);
iframe.src = url;
});
}

// Posts |message| to |target| and resolves the promise with the response coming
// back from |target|.
function sendMessageAndGetResponse(target, message) {
return new Promise((resolve) => {
window.messageResponseCallback = resolve;
target.postMessage(message, "*");
});
}


function onMessage(e) {
if (window.messageResponseCallback) {
window.messageResponseCallback(e.data);
window.messageResponseCallback = null;
}
}

window.addEventListener("message", onMessage);

// Waits for |load_timeout| before resolving the promise. It will resolve the
// promise sooner if a message event with |e.data.id| of |id| is received.
// In such a case the response is the contents of the message |e.data.contents|.
// Otherwise, returns false (when timeout occurs).
function waitForMessageOrTimeout(t, id, load_timeout) {
return new Promise((resolve) => {
window.addEventListener(
"message",
(e) => {
if (!e.data || e.data.id !== id)
return;
resolve(e.data.contents);
}
);
t.step_timeout(() => { resolve(false); }, load_timeout);
});
}

function createIframe(container, attributes) {
var new_iframe = document.createElement("iframe");
for (attr_name in attributes)
new_iframe.setAttribute(attr_name, attributes[attr_name]);
container.appendChild(new_iframe);
return new_iframe;
}

// Returns a promise which is resolved when |load| event is dispatched for |e|.
function wait_for_load(e) {
return new Promise((resolve) => {
e.addEventListener("load", resolve);
});
}

setup(() => {
window.reporting_observer_instance = new ReportingObserver((reports, observer) => {
if (window.reporting_observer_callback) {
reports.forEach(window.reporting_observer_callback);
}
}, {types: ["permissions-policy-violation"]});
window.reporting_observer_instance.observe();
window.reporting_observer_callback = null;
});

// Waits for a violation in |feature| and source file containing |file_name|.
function wait_for_violation_in_file(feature, file_name) {
return new Promise( (resolve) => {
assert_equals(null, window.reporting_observer_callback);
window.reporting_observer_callback = (report) => {
var feature_match = (feature === report.body.featureId);
var file_name_match =
!file_name ||
(report.body.sourceFile.indexOf(file_name) !== -1);
if (feature_match && file_name_match) {
window.reporting_observer_callback = null;
resolve(report);
}
};
});
}
Loading