Source code
Revision control
Copy as Markdown
Other Tools
Test Info: Warnings
- This test has a WPT meta file that expects 1 subtest issues.
- This WPT test may be referenced by the following Test IDs:
- /service-workers/service-worker/sandboxed-iframe-navigator-serviceworker.https.html - WPT Dashboard Interop Dashboard
<!DOCTYPE html>
<title>Accessing navigator.serviceWorker in sandboxed iframe.</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/test-helpers.sub.js"></script>
<body>
<script>
var lastCallbackId = 0;
var callbacks = {};
function postMessageAndWaitResult(frame) {
return new Promise(function(resolve, reject) {
var id = ++lastCallbackId;
callbacks[id] = resolve;
frame.contentWindow.postMessage({id:id}, '*');
const timeout = 1000;
step_timeout(() => reject("no msg back after " + timeout + "ms"), timeout);
});
}
window.onmessage = function(e) {
message = e.data;
var id = message['id'];
var callback = callbacks[id];
delete callbacks[id];
callback(message.result);
};
promise_test(function(t) {
var url = 'resources/sandboxed-iframe-navigator-serviceworker-iframe.html';
var frame;
return with_iframe(url)
.then(function(f) {
frame = f;
add_result_callback(() => { frame.remove(); });
return postMessageAndWaitResult(f);
})
.then(function(result) {
assert_equals(result, 'ok');
});
}, 'Accessing navigator.serviceWorker in normal iframe should not throw.');
promise_test(function(t) {
var url = 'resources/sandboxed-iframe-navigator-serviceworker-iframe.html';
var frame;
return with_sandboxed_iframe(url, 'allow-scripts')
.then(function(f) {
frame = f;
add_result_callback(() => { frame.remove(); });
return postMessageAndWaitResult(f);
})
.then(function(result) {
assert_equals(
result,
'navigator.serviceWorker failed: SecurityError');
});
}, 'Accessing navigator.serviceWorker in sandboxed iframe should throw.');
promise_test(function(t) {
var url = 'resources/sandboxed-iframe-navigator-serviceworker-iframe.html';
var frame;
return with_sandboxed_iframe(url, 'allow-scripts allow-same-origin')
.then(function(f) {
frame = f;
add_result_callback(() => { frame.remove(); });
return postMessageAndWaitResult(f);
})
.then(function(result) {
assert_equals(result, 'ok');
});
},
'Accessing navigator.serviceWorker in sandboxed iframe with ' +
'allow-same-origin flag should not throw.');
promise_test(function(t) {
var url = 'resources/sandboxed-iframe-navigator-serviceworker-iframe.html';
var frame;
return new Promise(function(resolve) {
frame = document.createElement('iframe');
add_result_callback(() => { frame.remove(); });
frame.sandbox = '';
frame.src = url;
frame.onload = resolve;
document.body.appendChild(frame);
// Switch the sandbox attribute while loading the iframe.
frame.sandbox = 'allow-scripts allow-same-origin';
})
.then(function() {
return postMessageAndWaitResult(frame)
})
.then(function(result) {
// The HTML spec seems to say that changing the sandbox attribute
// after the iframe is inserted into its parent document does not
// affect the sandboxing. If that's true, the frame should still
// act as if it still doesn't have
// 'allow-scripts allow-same-origin' set and throw a SecurityError.
//
// 1) From Section 4.8.5 "The iframe element":
// "When an iframe element is inserted into a document that has a
// browsing context, the user agent must create a new browsing
// context..."
// 2) "Create a new browsing context" expands to Section 7.1
// "Browsing contexts", which includes creating a Document and
// "Implement the sandboxing for document."
// 3) "Implement the sandboxing" expands to Section 7.6 "Sandboxing",
// which includes "populate document's active sandboxing flag set".
//
// It's not clear whether navigation subsequently creates a new
// Document, but I'm assuming it wouldn't.
assert_true(
false,
'should NOT get message back from a sandboxed frame where scripts are not allowed to execute');
})
.catch(msg => {
assert_true(msg.startsWith('no msg back'), 'expecting error message "no msg back"');
});
}, 'Switching iframe sandbox attribute while loading the iframe');
</script>
</body>