Source code
Revision control
Copy as Markdown
Other Tools
Test Info: Warnings
- This test has a WPT meta file that expects 3 subtest issues.
- This WPT test may be referenced by the following Test IDs:
- /web-install/navigator-install-sandboxed-iframe.tentative.https.html - WPT Dashboard Interop Dashboard
<!DOCTYPE html>
<title>navigator.install() in sandboxed and non-sandboxed iframes</title>
<link rel="help" href="https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/main/WebInstall/explainer.md">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<body>
<script>
var lastCallbackId = 0;
var callbacks = {};
function postMessageAndWaitResult(frame) {
return new Promise(function(resolve) {
var id = ++lastCallbackId;
callbacks[id] = resolve;
frame.contentWindow.postMessage({id: id}, '*');
});
}
window.onmessage = function(e) {
var message = e.data;
var id = message['id'];
var callback = callbacks[id];
delete callbacks[id];
callback(message);
};
function with_iframe(url) {
return new Promise(function(resolve) {
var frame = document.createElement('iframe');
frame.src = url;
frame.onload = function() { resolve(frame); };
document.body.appendChild(frame);
});
}
function with_sandboxed_iframe(url, sandbox) {
return new Promise(function(resolve) {
var frame = document.createElement('iframe');
frame.sandbox = sandbox;
frame.src = url;
frame.onload = function() { resolve(frame); };
document.body.appendChild(frame);
});
}
const helper_url = 'resources/navigator-install-iframe-helper.html';
promise_test(function(t) {
return with_sandboxed_iframe(helper_url, 'allow-scripts')
.then(function(frame) {
t.add_cleanup(() => { frame.remove(); });
return postMessageAndWaitResult(frame);
})
.then(function(message) {
// In a sandboxed iframe without allow-same-origin, the origin is
// opaque. The permissions policy default allowlist of "self" does not
// include opaque origins, so the permissions policy check fails first
// with a SecurityError.
assert_equals(message.errorName, 'SecurityError',
'Should throw SecurityError in sandboxed iframe');
});
}, 'navigator.install() in sandboxed iframe (allow-scripts) should throw ' +
'SecurityError.');
promise_test(function(t) {
return with_sandboxed_iframe(
helper_url, 'allow-scripts allow-same-origin')
.then(function(frame) {
t.add_cleanup(() => { frame.remove(); });
return postMessageAndWaitResult(frame);
})
.then(function(message) {
// With allow-same-origin, the iframe retains its real origin, so the
// permissions policy check passes. However, navigator.install()
// disallows ALL sandboxed contexts, so the sandbox flags check fails
// with a SecurityError.
assert_equals(message.errorName, 'SecurityError',
'Should throw SecurityError in sandboxed iframe even with ' +
'allow-same-origin');
});
}, 'navigator.install() in sandboxed iframe (allow-scripts ' +
'allow-same-origin) should throw SecurityError.');
promise_test(function(t) {
return with_iframe(helper_url)
.then(function(frame) {
t.add_cleanup(() => { frame.remove(); });
return postMessageAndWaitResult(frame);
})
.then(function(message) {
// A regular same-origin iframe passes the permissions policy and
// sandbox checks, but fails the main-frame check with an
// InvalidStateError.
assert_equals(message.errorName, 'InvalidStateError',
'Should throw InvalidStateError in non-main-frame iframe');
});
}, 'navigator.install() in a same-origin iframe should throw ' +
'InvalidStateError.');
</script>
</body>