<!DOCTYPE html>
<title>Tests that a portal can adopt its predecessor</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
  function waitForCompletion(targetTest) {
    return new Promise((resolve, reject) => {
      window.addEventListener("message", ({data: {test, message}}) => {
         if (test === targetTest)
           resolve(message);
      });
    });
  }

  promise_test(async () => {
    assert_implements("HTMLPortalElement" in self);
    var test = "adopt-once";
    window.open(`resources/portals-adopt-predecessor.html?test=${test}`);
    var message = await waitForCompletion(test);
    assert_equals(message, "adopted");
  }, "Tests that a portal can adopt its predecessor.");

  promise_test(async () => {
    assert_implements("HTMLPortalElement" in self);
    var test = "adopt-twice";
    window.open(`resources/portals-adopt-predecessor.html?test=${test}`);
    var message = await waitForCompletion(test);
    assert_equals(message, "passed");
  }, "Tests that trying to adopt the predecessor twice will throw an exception.");

  async_test(function(t) {
    assert_implements("HTMLPortalElement" in self);
    var test = "adopt-after-event";
    var bc = new BroadcastChannel(`test-${test}`);
    bc.onmessage = t.step_func_done(function(e) {
      assert_equals(e.data, "passed");
      bc.close();
    });
    window.open(`resources/portals-adopt-predecessor.html?test=${test}`);
  }, "Tests that trying to adopt the predecessor after the PortalActivateEvent will throw an exception.");

  promise_test(async t => {
    assert_implements("HTMLPortalElement" in self);
    var test = "adopt-and-activate";
    window.open(`resources/portals-adopt-predecessor.html?test=${test}`);
    var message = await waitForCompletion(test);
    assert_equals(message, "passed");
  }, "Tests that activating an adopted predecessor without inserting it works");

  async_test(t => {
    assert_implements("HTMLPortalElement" in self);
    var test = "adopt-attach-remove";
    var bc = new BroadcastChannel(`test-${test}`);
    bc.onmessage = t.step_func_done(function(e) {
      assert_equals(e.data, "passed");
      bc.close();
    });
    window.open(`resources/portals-adopt-predecessor.html?test=${test}`);
  }, "Tests that an adopting, inserting and then removing a predecessor works correctly");

  async_test(t => {
    assert_implements("HTMLPortalElement" in self);
    var test = "adopt-and-discard";
    var bc = new BroadcastChannel(`test-${test}`);
    bc.onmessage = t.step_func_done(function(e) {
      assert_equals(e.data, "passed");
      bc.close();
    });
    window.open(`resources/portals-adopt-predecessor.html?test=${test}`);
  }, "Tests that the adopted predecessor is destroyed if it isn't inserted");

  async_test(t => {
    assert_implements("HTMLPortalElement" in self);
    var test = "adopt-to-disconnected-node";
    var bc = new BroadcastChannel(`test-${test}`);
    bc.onmessage = t.step_func_done(function(e) {
      assert_equals(e.data, "passed");
      bc.close();
    });
    window.open(`resources/portals-adopt-predecessor.html?test=${test}`);
  }, "Tests that an adopted portal can be inserted into a disconnected node.");
</script>
