<!DOCTYPE HTML>
<html>
<head>
  <meta charset="utf-8">
  <title>Auto refreshing pages shouldn't add an entry to session history</title>
  <script src="/tests/SimpleTest/SimpleTest.js"></script>
  <link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
  <script>
    const REFRESH_REDIRECT_TIMER = 15;

    // 2 tests (same and cross origin) consisting of 2 refreshes of maximum 1 seconds
    // 2 tests (same and cross origin) consisting of 2 refreshes of REFRESH_REDIRECT_TIMER seconds
    // => We need (2 * 1) + (2 * 15) seconds
    SimpleTest.requestLongerTimeout(3);
    SimpleTest.waitForExplicitFinish();

    const SJS = new URL("file_bug1742865.sjs", location.href);
    const SJS_OUTER = new URL("file_bug1742865_outer.sjs", location.href);
    const SCROLL = 500;

    let tolerance;
    function setup() {
      return SpecialPowers.spawn(window.top, [], () => {
        return SpecialPowers.getDOMWindowUtils(content.window).getResolution();
      }).then(resolution => {
        // Allow a half pixel difference if the top document's resolution is lower
        // than 1.0 because the scroll position is aligned with screen pixels
        // instead of CSS pixels.
        tolerance = resolution < 1.0 ? 0.5 : 0.0;
      });
    }

    function checkScrollPosition(scrollPosition, shouldKeepScrollPosition) {
      isfuzzy(scrollPosition, shouldKeepScrollPosition ? SCROLL : 0, tolerance,
              `Scroll position ${shouldKeepScrollPosition ? "should" : "shouldn't"} be maintained for meta refresh`);
    }

    function openWindowAndCheckRefresh(url, params, shouldAddToHistory, shouldKeepScrollPosition) {
      info(`Running test for ${JSON.stringify(params)}`);

      url = new URL(url);
      Object.entries(params).forEach(([k, v]) => { url.searchParams.append(k, v) });
      url.searchParams.append("scrollTo", SCROLL);

      let resetURL = new URL(SJS);
      resetURL.search = "?reset";
      return fetch(resetURL).then(() => {
        return new Promise((resolve) => {
          let count = 0;
          window.addEventListener("message", function listener({ data: { commandType, commandData = {} } }) {
            if (commandType == "onChangedInputValue") {
              let { historyLength, inputValue } = commandData;

              if (shouldAddToHistory) {
                is(historyLength, count, "Auto-refresh should add entries to session history");
              } else {
                is(historyLength, 1, "Auto-refresh shouldn't add entries to session history");
              }

              is(inputValue, "1234", "Input's value should have been changed");

              win.postMessage("loadNext", "*");
              return;
            }

            is(commandType, "pageShow", "Unknown command type");

            let { inputValue, scrollPosition } = commandData;

            switch (++count) {
              // file_bug1742865.sjs causes 3 loads:
              //  * first load, returns first meta refresh
              //  * second load, caused by first meta refresh, returns second meta refresh
              //  * third load, caused by second meta refresh, doesn't return a meta refresh
              case 2:
                checkScrollPosition(scrollPosition, shouldKeepScrollPosition);
                break;
              case 3:
                checkScrollPosition(scrollPosition, shouldKeepScrollPosition);
                win.postMessage("changeInputValue", "*");
                break;
              case 4:
                win.postMessage("back", "*");
                break;
              case 5:
                is(inputValue, "1234", "Entries for auto-refresh should be attached to session history");
                checkScrollPosition(scrollPosition, shouldKeepScrollPosition);
                removeEventListener("message", listener);
                win.close();
                resolve();
                break;
            }
          });
          let win = window.open(url);
        });
      });
    }

    function doTest(seconds, crossOrigin, shouldAddToHistory, shouldKeepScrollPosition) {
      let params = {
        seconds,
        crossOrigin,
      };

      return openWindowAndCheckRefresh(SJS, params, shouldAddToHistory, shouldKeepScrollPosition).then(() =>
        openWindowAndCheckRefresh(SJS_OUTER, params, shouldAddToHistory, shouldKeepScrollPosition)
      );
    }

    async function runTest() {
      const FAST = Math.min(1, REFRESH_REDIRECT_TIMER);
      const SLOW = REFRESH_REDIRECT_TIMER + 1;
      let tests = [
        // [ time, crossOrigin, shouldAddToHistory, shouldKeepScrollPosition ]
        [ FAST, false, false, true ],
        [ FAST, true, false, false ],
        [ SLOW, false, false, true ],
        [ SLOW, true, true, false ],
      ];

      await setup();

      for (let [ time, crossOrigin, shouldAddToHistory, shouldKeepScrollPosition ] of tests) {
        await doTest(time, crossOrigin, shouldAddToHistory, shouldKeepScrollPosition);
      }

      SimpleTest.finish();
    }
  </script>
</head>
<body onload="runTest();">
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test"></pre>
</body>
</html>
