<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<body>
<script type="module">
import {MojoWebTestHelper, MojoWebTestHelperRemote} from '/gen/content/test/data/mojo_web_test_helper_test.mojom.m.js';
function frameLoaded(frame) {
return new Promise(
resolve => frame.addEventListener('load', resolve, {once: true}));
}
promise_test(async () => {
let frame = document.createElement("iframe");
let promise = frameLoaded(frame);
document.body.appendChild(frame);
await promise;
// Save a reference to the Mojo object from the child frame so that we can
// make calls to it after the context has been destroyed.
let frameMojo = frame.contentWindow.Mojo;
document.body.removeChild(frame);
const {handle0, handle1} = frameMojo.createMessagePipe();
let helper = new MojoWebTestHelperRemote(handle0);
frameMojo.bindInterface(MojoWebTestHelper.$interfaceName, handle1);
try {
await helper.reverse("hello world.");
assert_unreached();
} catch (e) {
// Connection failure expected.
}
}, "Mojo object is safe to use after its frame has been detached");
promise_test(async () => {
let frame = document.createElement("iframe");
let promise = frameLoaded(frame);
document.body.appendChild(frame);
await promise;
// Save a reference to the MojoInterfaceInterceptor constructor from the child
// frame so that we can be used after the context has been destroyed.
let frameMojoInterfaceInterceptor =
frame.contentWindow.MojoInterfaceInterceptor;
document.body.removeChild(frame);
let interceptor = new frameMojoInterfaceInterceptor(
MojoWebTestHelper.$interfaceName);
try {
interceptor.start();
assert_unreached();
} catch (e) {
// Failure expected.
}
}, "MojoInterfaceInterceptor constructor is safe to use after its frame has been detached");
promise_test(async () => {
let frame = document.createElement("iframe");
let promise = frameLoaded(frame);
document.body.appendChild(frame);
await promise;
// Create the interceptor while the frame is attached so that it is associated
// with the frame's execution context.
let interceptor = new frame.contentWindow.MojoInterfaceInterceptor(
MojoWebTestHelper.$interfaceName);
document.body.removeChild(frame);
try {
interceptor.start();
assert_unreached();
} catch (e) {
// Failure expected.
}
}, "MojoInterfaceInterceptor can't be started after its frame has been detached");
promise_test(async () => {
let frame = document.createElement("iframe");
let promise = frameLoaded(frame);
document.body.appendChild(frame);
await promise;
// Create the interceptor and start it while the frame is attached.
let interceptor = new frame.contentWindow.MojoInterfaceInterceptor(
MojoWebTestHelper.$interfaceName);
interceptor.start();
document.body.removeChild(frame);
// stop() will succeed because it is implicitly called when the execution
// context is destroyed.
interceptor.stop();
}, "MojoInterfaceInterceptor is stopped on frame destruction");
</script>
</body>