<!doctype html>
<meta name="timeout" content="long">
<title>Cross-Origin-Embedder-Policy header and nested navigable resource without such header</title>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src="/common/get-host-info.sub.js"></script>
<script src="/common/utils.js"></script> <!-- Use token() to allow running tests in parallel -->
<div id=log></div>
<script>
async_test(t => {
  const frame = document.createElement("iframe");
  t.add_cleanup(() => frame.remove());
  t.step_timeout(() => {
    // Make sure the iframe didn't load. See https://github.com/whatwg/html/issues/125 for why a
    // timeout is used here. Long term all network error handling should be similar and have a
    // reliable event.
    assert_equals(frame.contentDocument, null);
    t.done();
  }, 500);
  frame.src = "/common/blank.html";
  document.body.append(frame);
  assert_equals(frame.contentDocument.body.localName, "body");
}, `"require-corp" top-level: navigating a frame to "none" should fail`);

async_test(t => {
  const frame = document.createElement("iframe");
  t.add_cleanup(() => frame.remove());
  const bc = new BroadcastChannel(token());
  bc.onmessage = t.step_func((event) => {
    assert_not_equals(frame.contentDocument, null);
    let payload = event.data;
    assert_equals(payload, "loaded");
    t.step_timeout(() => {
      assert_equals(frame.contentDocument, null);
      t.done();
    }, 2000);
  });
  frame.src = `resources/navigate-require-corp.sub.html?channelName=${bc.name}&to=/common/blank.html`;
  document.body.append(frame);
  assert_equals(frame.contentDocument.body.localName, "body");
}, `"require-corp" top-level: navigating a frame from "require-corp" to "none" should fail`);

async_test(t => {
  let pageLoaded = false;
  const bc = new BroadcastChannel(token());
  let finished = false;
  bc.onmessage = t.step_func((event) => {
    let payload = event.data;
    assert_equals(payload, "loaded");
    pageLoaded = true;
  });

  const bc2 = new BroadcastChannel(token());
  bc2.onmessage = t.step_func_done((event) => {
    let payload = event.data;
    assert_equals(payload, "loaded");
    assert_equals(pageLoaded, true);
  });

  const win = window.open(`resources/navigate-none.sub.html?channelName=${bc.name}&to=navigate-none.sub.html?channelName=${bc2.name}`, "_blank", "noopener");
  assert_equals(win, null);
}, `"require-corp" top-level: creating a noopener "none" popup should succeed`);

async_test(t => {
  let pageLoaded = false;
  const bc = new BroadcastChannel(token());
  bc.onmessage = t.step_func_done((event) => {
    pageLoaded = true;
    let payload = event.data;
    assert_equals(payload, "loaded");
  });

  const win = window.open(`resources/navigate-none.sub.html?channelName=${bc.name}&to=/common/blank.html`, "_blank");
  t.add_cleanup(() => win.close());
}, `"require-corp" top-level: creating a "none" popup should succeed.`);

[
  {
    "name": "",
    "title": "as popup"
  },
  {
    "name": "noopener",
    "title": "as noopener popup"
  },
  {
    "name": "clear opener",
    "title": "as popup with opener set to null"
  }
].forEach(({name, title}) => {
  async_test(t => {
    let pageLoaded = false;
    const bc = new BroadcastChannel(token());
    bc.onmessage = t.step_func(event => {
      pageLoaded = true;
      const payload = event.data;
      assert_equals(payload, "loaded");
    });

    const bc2 = new BroadcastChannel(token());
    bc2.onmessage = t.step_func_done(event => {
      const payload = event.data;
      assert_equals(payload, "loaded");
      assert_equals(pageLoaded, true);
    });

    let clearOpener = "";
    if (name === "clear opener") {
      clearOpener = "&clearOpener=true"
    }

    let noopener = undefined;
    if (name === "noopener") {
      noopener = "noopener"
    }

    const win = window.open(`resources/navigate-require-corp.sub.html?channelName=${bc.name}${clearOpener}&to=navigate-none.sub.html?channelName=${bc2.name}`, "_blank", noopener);
    if (name === "noopener") {
      assert_equals(win, null);
    } else {
      t.add_cleanup(() => win.close());
    }
  }, `"require-corp" top-level (${title}): navigating to "none" should succeed`);
});

promise_test(async t => {
  const response = await fetch(get_host_info().HTTPS_REMOTE_ORIGIN+"/html/cross-origin-embedder-policy/resources/nothing-cross-origin-corp.txt", {mode: "no-cors"});
  assert_equals(response.type, "opaque");
}, `"require-corp" top-level: fetch() to CORP: cross-origin response should succeed`);

promise_test(t => {
  return promise_rejects(t, new TypeError(), fetch(get_host_info().HTTPS_REMOTE_ORIGIN+"/common/blank.html", {mode: "no-cors"}));
}, `"require-corp" top-level: fetch() to response without CORP should fail`);
</script>
