<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=602256
-->
<head>
  <title>Test for Bug 602256</title>
</head>
<body onload="SimpleTest.executeSoon(run_test)">
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=602256">Mozilla Bug 602256</a>
<div id="content">
  <iframe id="iframe" src="start_historyframe.html"></iframe>
</div>
<pre id="test">
<script type="application/javascript">

/** Test for Bug 602256 */

var testWin = window.opener ? window.opener : window.parent;

var SimpleTest = testWin.SimpleTest;
function is() { testWin.is.apply(testWin, arguments); }

var gFrame = null;

function gState() {
  return location.hash.replace(/^#/, "");
}

function waitForLoad(aCallback) {
  function listener() {
    gFrame.removeEventListener("load", listener);
    SimpleTest.executeSoon(aCallback);
  }

  gFrame.addEventListener("load", listener);
}

function loadContent(aURL, aCallback) {
  waitForLoad(aCallback);

  gFrame.src = aURL;
}

function getURL() {
  return gFrame.contentDocument.documentURI;
}

function getContent() {
  return gFrame.contentDocument.getElementById("text").textContent;
}

var BASE_URI = "http://mochi.test:8888/tests/docshell/test/mochitest/";
var START = BASE_URI + "start_historyframe.html";
var URL1 = BASE_URI + "url1_historyframe.html";
var URL2 = BASE_URI + "url2_historyframe.html";

function run_test() {
  window.location.hash = "START";

  gFrame = document.getElementById("iframe");

  test_basic_inner_navigation();
}

function end_test() {
  testWin.done();
}

var gTestContinuation = null;
function continueAsync() {
  setTimeout(function() { gTestContinuation.next(); })
}

function test_basic_inner_navigation() {
  // Navigate the inner frame a few times
  loadContent(URL1, function() {
    is(getURL(), URL1, "URL should be correct");
    is(getContent(), "Test1", "Page should be correct");

    loadContent(URL2, function() {
      is(getURL(), URL2, "URL should be correct");
      is(getContent(), "Test2", "Page should be correct");

      // Test that history is working
      waitForLoad(function() {
        is(getURL(), URL1, "URL should be correct");
        is(getContent(), "Test1", "Page should be correct");

        waitForLoad(function() {
          is(getURL(), URL2, "URL should be correct");
          is(getContent(), "Test2", "Page should be correct");

          gTestContinuation = test_state_navigation();
          gTestContinuation.next();
        });
        window.history.forward();
      });
      window.history.back();
    });
  });
}

function* test_state_navigation() {
  window.location.hash = "STATE1";

  is(getURL(), URL2, "URL should be correct");
  is(getContent(), "Test2", "Page should be correct");

  window.location.hash = "STATE2";

  is(getURL(), URL2, "URL should be correct");
  is(getContent(), "Test2", "Page should be correct");

  window.addEventListener("popstate", (e) => {
    continueAsync();
  }, {once: true});
  window.history.back();
  yield;

  is(gState(), "STATE1", "State should be correct after going back");
  is(getURL(), URL2, "URL should be correct");
  is(getContent(), "Test2", "Page should be correct");

  window.addEventListener("popstate", (e) => {
    continueAsync();
  }, {once: true});
  window.history.forward();
  yield;

  is(gState(), "STATE2", "State should be correct after going forward");
  is(getURL(), URL2, "URL should be correct");
  is(getContent(), "Test2", "Page should be correct");

  window.addEventListener("popstate", (e) => {
    continueAsync();
  }, {once: true});
  window.history.back();
  yield;

  window.addEventListener("popstate", (e) => {
    continueAsync();
  }, {once: true});
  window.history.back();
  yield;

  is(gState(), "START", "State should be correct");
  is(getURL(), URL2, "URL should be correct");
  is(getContent(), "Test2", "Page should be correct");

  waitForLoad(function() {
    is(getURL(), URL1, "URL should be correct");
    is(getContent(), "Test1", "Page should be correct");

    waitForLoad(function() {
      is(gState(), "START", "State should be correct");
      is(getURL(), START, "URL should be correct");
      is(getContent(), "Start", "Page should be correct");

      end_test();
    });

    window.history.back();

    is(gState(), "START", "State should be correct after going back twice");
  });

  window.history.back();
  continueAsync();
  yield;
  is(gState(), "START", "State should be correct");
}
</script>
</pre>
</body>
</html>