Commit c9bf906a authored by Daisuke Akatsuka's avatar Daisuke Akatsuka
Browse files

Bug 1829161: Make the tab loading non-web-controlled page in _blank target as...

Bug 1829161: Make the tab loading non-web-controlled page in _blank target as 1-based. r=extension-reviewers,farre,rpl,Gijs

Differential Revision: https://phabricator.services.mozilla.com/D176238
parent 7baa01e4
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -258,6 +258,9 @@ skip-if = !crashreporter
https_first_disabled = true
[browser_ext_sessions_getRecentlyClosed_private.js]
[browser_ext_sessions_getRecentlyClosed_tabs.js]
support-files =
  file_has_non_web_controlled_blank_page_link.html
  wait-a-bit.sjs
[browser_ext_sessions_incognito.js]
[browser_ext_sessions_restore.js]
[browser_ext_sessions_restoreTab.js]
+80 −0
Original line number Diff line number Diff line
@@ -205,3 +205,83 @@ add_task(async function test_sessions_get_recently_closed_tabs() {

  await extension.unload();
});

add_task(
  async function test_sessions_get_recently_closed_for_loading_non_web_controlled_blank_page() {
    info("Prepare extension that calls browser.sessions.getRecentlyClosed()");
    let extension = ExtensionTestUtils.loadExtension({
      manifest: {
        permissions: ["sessions", "tabs"],
      },
      background: async () => {
        browser.test.onMessage.addListener(async msg => {
          if (msg == "check-sessions") {
            let recentlyClosed = await browser.sessions.getRecentlyClosed();
            browser.test.sendMessage("recentlyClosed", recentlyClosed);
          }
        });
      },
    });

    info(
      "Open a page having a link for non web controlled page in _blank target"
    );
    const testRoot = getRootDirectory(gTestPath).replace(
      "chrome://mochitests/content",
      "https://example.com"
    );
    let url = `${testRoot}file_has_non_web_controlled_blank_page_link.html`;
    let win = await BrowserTestUtils.openNewBrowserWindow();
    BrowserTestUtils.loadURIString(win.gBrowser.selectedBrowser, url);
    await BrowserTestUtils.browserLoaded(
      win.gBrowser.selectedBrowser,
      false,
      url
    );

    info("Open the non web controlled page in _blank target");
    let onNewTabOpened = new Promise(resolve =>
      win.gBrowser.addTabsProgressListener({
        onStateChange(browser, webProgress, request, stateFlags, status) {
          if (stateFlags & Ci.nsIWebProgressListener.STATE_START) {
            win.gBrowser.removeTabsProgressListener(this);
            resolve(win.gBrowser.getTabForBrowser(browser));
          }
        },
      })
    );
    let targetUrl = await SpecialPowers.spawn(
      win.gBrowser.selectedBrowser,
      [],
      () => {
        const target = content.document.querySelector("a");
        EventUtils.synthesizeMouseAtCenter(target, {}, content);
        return target.href;
      }
    );
    let tab = await onNewTabOpened;

    info("Remove tab while loading to get getRecentlyClosed()");
    await extension.startup();
    let sessionUpdatePromise = BrowserTestUtils.waitForSessionStoreUpdate(tab);
    BrowserTestUtils.removeTab(tab);
    await sessionUpdatePromise;

    info("Check the result of getRecentlyClosed()");
    extension.sendMessage("check-sessions");
    let recentlyClosed = await extension.awaitMessage("recentlyClosed");
    checkTabInfo(
      {
        index: 1,
        url: targetUrl,
        title: targetUrl,
        favIconUrl: undefined,
        selected: undefined,
      },
      recentlyClosed[0].tab
    );

    await extension.unload();
    await BrowserTestUtils.closeWindow(win);
  }
);
+5 −0
Original line number Diff line number Diff line
<style>
a { display: block; }
</style>

<a href="wait-a-bit.sjs" target="_blank">wait-a-bit - _blank target</a>
+23 −0
Original line number Diff line number Diff line
/* Any copyright is dedicated to the Public Domain.
   http://creativecommons.org/publicdomain/zero/1.0/ */

"use strict";

// eslint-disable-next-line mozilla/no-redeclare-with-import-autofix
const { setTimeout } = ChromeUtils.importESModule(
  "resource://gre/modules/Timer.sys.mjs"
);

async function handleRequest(request, response) {
  response.seizePower();

  await new Promise(r => setTimeout(r, 2000));

  response.write("HTTP/1.1 200 OK\r\n");
  const body = "<title>wait a bit</title><body>ok</body>";
  response.write("Content-Type: text/html\r\n");
  response.write(`Content-Length: ${body.length}\r\n`);
  response.write("\r\n");
  response.write(body);
  response.finish();
}
+2 −1
Original line number Diff line number Diff line
@@ -165,7 +165,8 @@ var SessionHistoryInternal = {
            browsingContext.mostRecentLoadingSessionHistoryEntry
          ),
        ],
        index: 0,
        // Set 1 to the index, as the array of session entries is 1-based.
        index: 1,
        fromIdx: -1,
        requestedIndex: browsingContext.sessionHistory.requestedIndex + 1,
      };