<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>

<window id="301397Test"
        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
        width="600"
        height="600"
        onload="setTimeout(runTest, 0);"
        title="bug 301397 test">

  <script type="application/javascript" src= "chrome://mochikit/content/chrome-harness.js" />
  <script type="application/javascript" src="docshell_helpers.js" />
  <script type="application/javascript"><![CDATA[
    Services.prefs.setBoolPref("browser.navigation.requireUserInteraction", false);
  
    ////
    // Verifies that the given string exists in the innerHTML of the iframe
    // content.
    //
    async function verifyIframeInnerHtml(string) {
      var iframeInnerHtml = await SpecialPowers.spawn(document.getElementById("content"), [string], (string) =>
          content.document.getElementById("iframe").contentDocument.body.innerHTML);
      ok(iframeInnerHtml.includes(string),
         "iframe contains wrong document: " + iframeInnerHtml);
    }

    ////
    // Generator function for test steps for bug 301397:
    // The correct page should be displayed in an iframe when
    // navigating back and forwards, when the parent page
    // occupies multiple spots in the session history.
    //
    async function runTest()
    {
      // Make sure the bfcache is enabled.
      enableBFCache(8);

      // Load a dummy page.
      await promisePageNavigation({
        uri: getHttpUrl("generic.html"),
      });

      // Load a page containing an iframe.
      await promisePageNavigation({
        uri: getHttpUrl("bug301397_1.html"),
        eventsToListenFor: ["pageshow", "pagehide"],
        expectedEvents: [ { type: "pagehide",
                            title: "generic page",
                            persisted: true },
                          { type: "pageshow",
                            title: "iframe content #1",
                            persisted: false },   // false on initial load
                          { type: "pageshow",
                            title: "iframe parent",
                            persisted: false } ], // false on initial load
      });

      // Click a link in the iframe to cause the iframe to navigate
      // to a new page, and wait until the related pagehide/pageshow
      // events have occurred.
      let waitForLinkNavigation = promisePageEvents({
        eventsToListenFor: ["pageshow", "pagehide"],
        expectedEvents: [ { type: "pagehide",
                            title: "iframe content #1",
                            persisted: false },   // false, subframe nav
                          { type: "pageshow",
                            title: "iframe content #2",
                            persisted: false } ], // false on initial load
      });
      SpecialPowers.spawn(document.getElementById("content"), [], function() {
        let iframe = content.document.getElementById("iframe");
        let link = iframe.contentDocument.getElementById("link");
        let event = iframe.contentDocument.createEvent("MouseEvents");
        event.initMouseEvent("click", true, true, iframe.contentWindow,
          0, 0, 0, 0, 0,
          false, false, false, false,
          0, null);
        link.dispatchEvent(event);
      });
      await waitForLinkNavigation;

      // Load another dummy page.  Verify that both the outgoing parent and
      // iframe pages are stored in the bfcache.
      await promisePageNavigation({
        uri: getHttpUrl("bug301397_4.html"),
        eventsToListenFor: ["pageshow", "pagehide"],
        expectedEvents: [ { type: "pagehide",
                            title: "iframe parent",
                            persisted: true },
                          { type: "pagehide",
                            title: "iframe content #2",
                            persisted: true },
                          { type: "pageshow",
                            title: "dummy page, no iframe",
                            persisted: false } ],  // false on initial load
      });

      // Go back.  The iframe should show the second page loaded in it.
      // Both the parent and the iframe pages should be loaded from
      // the bfcache.
      await promisePageNavigation({
        back: true,
        eventsToListenFor: ["pageshow", "pagehide"],
        expectedEvents: [ { type: "pagehide",
                            title: "dummy page, no iframe",
                            persisted: true },
                          { type: "pageshow",
                            persisted: true,
                            title: "iframe content #2" },
                          { type: "pageshow",
                            persisted: true,
                            title: "iframe parent" } ],
      });

      verifyIframeInnerHtml("You made it");
      
      // Go gack again.  The iframe should show the first page loaded in it.
      await promisePageNavigation({
        back: true,
        eventsToListenFor: ["pageshow", "pagehide"],
        expectedEvents: [ { type: "pagehide",
                            title: "iframe content #2",
                            persisted: false },  // false, subframe nav
                          { type: "pageshow",
                            title: "iframe content #1",
                            // false since this page was never stored
                            // in the bfcache in the first place
                            persisted: false } ], 
      });

      verifyIframeInnerHtml("go to next page");
      
      // Go back to the generic page.  Now go forward to the last page,
      // again verifying that the iframe shows the first and second
      // pages in order.
      await promisePageNavigation({
        back: true,
        eventsToListenFor: ["pageshow", "pagehide"],
        expectedEvents: [ { type: "pagehide",
                            title: "iframe parent",
                            persisted: true },
                          { type: "pagehide",
                            title: "iframe content #1",
                            persisted: true },
                          { type: "pageshow",
                            title: "generic page",
                            persisted: true } ], 
      });

      await promisePageNavigation({
        forward: true,
        eventsToListenFor: ["pageshow"],
        expectedEvents: [ {type: "pageshow",
                           title: "iframe content #1",
                           persisted: true},
                          {type: "pageshow",
                           title: "iframe parent",
                           persisted: true} ],
      });

      verifyIframeInnerHtml("go to next page");
      
      await promisePageNavigation({
        forward: true,
        eventsToListenFor: ["pageshow", "pagehide"],
        expectedEvents: [ { type: "pagehide",
                            title: "iframe content #1",
                            persisted: false },   // false, subframe nav
                          { type: "pageshow",
                            title: "iframe content #2",
                            // false because the page wasn't stored in 
                            // bfcache last time it was unloaded
                            persisted: false } ], 
      });

      verifyIframeInnerHtml("You made it");
      
      await promisePageNavigation({
        forward: true,
        eventsToListenFor: ["pageshow", "pagehide"],
        expectedEvents: [ { type: "pagehide",
                            title: "iframe parent",
                            persisted: true },
                          { type: "pagehide",
                            title: "iframe content #2",
                            persisted: true },
                          { type: "pageshow",
                            title: "dummy page, no iframe",
                            persisted: true } ],
      });

      // Go back once more, and again verify that the iframe shows the
      // second page loaded in it.
      await promisePageNavigation({
        back: true,
        eventsToListenFor: ["pageshow", "pagehide"],
        expectedEvents: [ { type: "pagehide",
                            title: "dummy page, no iframe",
                            persisted: true },
                          { type: "pageshow",
                            persisted: true,
                            title: "iframe content #2" },
                          { type: "pageshow",
                            persisted: true,
                            title: "iframe parent" } ],
      });

      verifyIframeInnerHtml("You made it");
      
      Services.prefs.clearUserPref("browser.navigation.requireUserInteraction");
      // Tell the framework the test is finished.
      finish();
    }
    
  ]]></script>

  <browser type="content" primary="true" flex="1" id="content" messagemanagergroup="test" remote="true" />
</window>