tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

browser_documentnavigation.js (12253B)


      1 /*
      2 * This test checks that focus is adjusted properly in a browser when pressing F6 and Shift+F6.
      3 * There are additional tests in dom/tests/mochitest/chrome/test_focus_docnav.xul which test
      4 * non-browser cases.
      5 */
      6 
      7 var testPage1 =
      8  "data:text/html,<html id='html1'><body id='body1'><button id='button1'>Tab 1</button></body></html>";
      9 var testPage2 =
     10  "data:text/html,<html id='html2'><body id='body2'><button id='button2'>Tab 2</button></body></html>";
     11 var testPage3 =
     12  "data:text/html,<html id='html3'><body id='body3' contenteditable='true'><button id='button3'>Tab 3</button></body></html>";
     13 
     14 var fm = Services.focus;
     15 
     16 async function expectFocusOnF6(
     17  backward,
     18  expectedDocument,
     19  expectedElement,
     20  onContent,
     21  desc
     22 ) {
     23  if (onContent) {
     24    let success = await SpecialPowers.spawn(
     25      gBrowser.selectedBrowser,
     26      [expectedElement],
     27      async function (expectedElementId) {
     28        content.lastResult = "";
     29        let contentExpectedElement =
     30          content.document.getElementById(expectedElementId);
     31        if (!contentExpectedElement) {
     32          // Element not found, so look in the child frames.
     33          for (let f = 0; f < content.frames.length; f++) {
     34            if (content.frames[f].document.getElementById(expectedElementId)) {
     35              contentExpectedElement = content.frames[f].document;
     36              break;
     37            }
     38          }
     39        } else if (contentExpectedElement.localName == "html") {
     40          contentExpectedElement = contentExpectedElement.ownerDocument;
     41        }
     42 
     43        if (!contentExpectedElement) {
     44          return null;
     45        }
     46 
     47        contentExpectedElement.addEventListener(
     48          "focus",
     49          function () {
     50            let details =
     51              Services.focus.focusedWindow.document.documentElement.id;
     52            if (Services.focus.focusedElement) {
     53              details += "," + Services.focus.focusedElement.id;
     54            }
     55 
     56            // Assign the result to a temporary place, to be used
     57            // by the next spawn call.
     58            content.lastResult = details;
     59          },
     60          { capture: true, once: true }
     61        );
     62 
     63        return !!contentExpectedElement;
     64      }
     65    );
     66 
     67    ok(success, "expected element " + expectedElement + " was found");
     68 
     69    EventUtils.synthesizeKey("VK_F6", { shiftKey: backward });
     70 
     71    let expected = expectedDocument;
     72    if (!expectedElement.startsWith("html")) {
     73      expected += "," + expectedElement;
     74    }
     75 
     76    let result = await SpecialPowers.spawn(
     77      gBrowser.selectedBrowser,
     78      [],
     79      async () => {
     80        await ContentTaskUtils.waitForCondition(() => content.lastResult);
     81        return content.lastResult;
     82      }
     83    );
     84    is(result, expected, desc + " child focus matches");
     85  } else {
     86    let focusPromise = BrowserTestUtils.waitForEvent(window, "focus", true);
     87    EventUtils.synthesizeKey("VK_F6", { shiftKey: backward });
     88    await focusPromise;
     89  }
     90 
     91  if (typeof expectedElement == "string") {
     92    expectedElement = fm.focusedWindow.document.getElementById(expectedElement);
     93  }
     94 
     95  if (gMultiProcessBrowser && onContent) {
     96    expectedDocument = "main-window";
     97    expectedElement = gBrowser.selectedBrowser;
     98  }
     99 
    100  is(
    101    fm.focusedWindow.document.documentElement.id,
    102    expectedDocument,
    103    desc + " document matches"
    104  );
    105  is(
    106    fm.focusedElement,
    107    expectedElement,
    108    desc +
    109      " element matches (wanted: " +
    110      expectedElement.id +
    111      " got: " +
    112      fm.focusedElement.id +
    113      ")"
    114  );
    115 }
    116 
    117 // Load a page and navigate between it and the chrome window.
    118 add_task(async function () {
    119  let page1Promise = BrowserTestUtils.browserLoaded(
    120    gBrowser.selectedBrowser,
    121    false,
    122    testPage1
    123  );
    124  BrowserTestUtils.startLoadingURIString(gBrowser.selectedBrowser, testPage1);
    125  await page1Promise;
    126 
    127  // When the urlbar is focused, pressing F6 should focus the root of the content page.
    128  gURLBar.focus();
    129  await expectFocusOnF6(
    130    false,
    131    "html1",
    132    "html1",
    133    true,
    134    "basic focus content page"
    135  );
    136 
    137  // When the content is focused, pressing F6 should focus the urlbar.
    138  await expectFocusOnF6(
    139    false,
    140    "main-window",
    141    gURLBar.inputField,
    142    false,
    143    "basic focus content page urlbar"
    144  );
    145 
    146  // When a button in content is focused, pressing F6 should focus the urlbar.
    147  await expectFocusOnF6(
    148    false,
    149    "html1",
    150    "html1",
    151    true,
    152    "basic focus content page with button focused"
    153  );
    154 
    155  await SpecialPowers.spawn(gBrowser.selectedBrowser, [], async function () {
    156    return content.document.getElementById("button1").focus();
    157  });
    158 
    159  await expectFocusOnF6(
    160    false,
    161    "main-window",
    162    gURLBar.inputField,
    163    false,
    164    "basic focus content page with button focused urlbar"
    165  );
    166 
    167  // The document root should be focused, not the button
    168  await expectFocusOnF6(
    169    false,
    170    "html1",
    171    "html1",
    172    true,
    173    "basic focus again content page with button focused"
    174  );
    175 
    176  // Check to ensure that the root element is focused
    177  await SpecialPowers.spawn(gBrowser.selectedBrowser, [], async function () {
    178    Assert.equal(
    179      content.document.activeElement,
    180      content.document.documentElement,
    181      "basic focus again content page with button focused child root is focused"
    182    );
    183  });
    184 });
    185 
    186 // Open a second tab. Document focus should skip the background tab.
    187 add_task(async function () {
    188  await BrowserTestUtils.openNewForegroundTab(gBrowser, testPage2);
    189 
    190  await expectFocusOnF6(
    191    false,
    192    "main-window",
    193    gURLBar.inputField,
    194    false,
    195    "basic focus content page and second tab urlbar"
    196  );
    197  await expectFocusOnF6(
    198    false,
    199    "html2",
    200    "html2",
    201    true,
    202    "basic focus content page with second tab"
    203  );
    204 
    205  BrowserTestUtils.removeTab(gBrowser.selectedTab);
    206 });
    207 
    208 // Shift+F6 should navigate backwards. There's only one document here so the effect
    209 // is the same.
    210 add_task(async function () {
    211  gURLBar.focus();
    212  await expectFocusOnF6(
    213    true,
    214    "html1",
    215    "html1",
    216    true,
    217    "back focus content page"
    218  );
    219  await expectFocusOnF6(
    220    true,
    221    "main-window",
    222    gURLBar.inputField,
    223    false,
    224    "back focus content page urlbar"
    225  );
    226 });
    227 
    228 // Open the sidebar and navigate between the sidebar, content and top-level window
    229 add_task(async function () {
    230  let sidebar = document.getElementById("sidebar");
    231 
    232  let loadPromise = BrowserTestUtils.waitForEvent(sidebar, "load", true);
    233  SidebarController.toggle("viewBookmarksSidebar");
    234  await loadPromise;
    235 
    236  gURLBar.focus();
    237  await expectFocusOnF6(
    238    false,
    239    "bookmarksPanel",
    240    sidebar.contentDocument
    241      .getElementById("search-box")
    242      .shadowRoot.querySelector("input"),
    243    false,
    244    "focus with sidebar open sidebar"
    245  );
    246  await expectFocusOnF6(
    247    false,
    248    "html1",
    249    "html1",
    250    true,
    251    "focus with sidebar open content"
    252  );
    253  await expectFocusOnF6(
    254    false,
    255    "main-window",
    256    gURLBar.inputField,
    257    false,
    258    "focus with sidebar urlbar"
    259  );
    260 
    261  // Now go backwards
    262  await expectFocusOnF6(
    263    true,
    264    "html1",
    265    "html1",
    266    true,
    267    "back focus with sidebar open content"
    268  );
    269 
    270  // Bug 2006225: sidebar.revamp introduces a regression where the "X" button receives
    271  // focus instead of the search input.
    272  let expectedSidebarFocusElement = Services.prefs.getBoolPref("sidebar.revamp")
    273    ? sidebar.contentDocument
    274        .getElementById("sidebar-panel-close")
    275        .shadowRoot.querySelector("#main-button")
    276    : sidebar.contentDocument
    277        .getElementById("search-box")
    278        .shadowRoot.querySelector("input");
    279  await expectFocusOnF6(
    280    true,
    281    "bookmarksPanel",
    282    expectedSidebarFocusElement,
    283    false,
    284    "back focus with sidebar open sidebar"
    285  );
    286  await expectFocusOnF6(
    287    true,
    288    "main-window",
    289    gURLBar.inputField,
    290    false,
    291    "back focus with sidebar urlbar"
    292  );
    293 
    294  SidebarController.toggle("viewBookmarksSidebar");
    295 });
    296 
    297 // Navigate when the downloads panel is open
    298 add_task(async function test_download_focus() {
    299  await pushPrefs(
    300    ["accessibility.tabfocus", 7],
    301    ["browser.download.autohideButton", false],
    302    ["security.dialog_enable_delay", 0]
    303  );
    304  await promiseButtonShown("downloads-button");
    305 
    306  let popupShownPromise = BrowserTestUtils.waitForEvent(
    307    document,
    308    "popupshown",
    309    true
    310  );
    311  EventUtils.synthesizeMouseAtCenter(
    312    document.getElementById("downloads-button"),
    313    {}
    314  );
    315  await popupShownPromise;
    316 
    317  gURLBar.focus();
    318  await expectFocusOnF6(
    319    false,
    320    "main-window",
    321    document.getElementById("downloadsHistory"),
    322    false,
    323    "focus with downloads panel open panel"
    324  );
    325  await expectFocusOnF6(
    326    false,
    327    "html1",
    328    "html1",
    329    true,
    330    "focus with downloads panel open"
    331  );
    332  await expectFocusOnF6(
    333    false,
    334    "main-window",
    335    gURLBar.inputField,
    336    false,
    337    "focus downloads panel open urlbar"
    338  );
    339 
    340  // Now go backwards
    341  await expectFocusOnF6(
    342    true,
    343    "html1",
    344    "html1",
    345    true,
    346    "back focus with downloads panel open"
    347  );
    348  await expectFocusOnF6(
    349    true,
    350    "main-window",
    351    document.getElementById("downloadsHistory"),
    352    false,
    353    "back focus with downloads panel open"
    354  );
    355  await expectFocusOnF6(
    356    true,
    357    "main-window",
    358    gURLBar.inputField,
    359    false,
    360    "back focus downloads panel open urlbar"
    361  );
    362 
    363  let downloadsPopup = document.getElementById("downloadsPanel");
    364  let popupHiddenPromise = BrowserTestUtils.waitForEvent(
    365    downloadsPopup,
    366    "popuphidden",
    367    true
    368  );
    369  downloadsPopup.hidePopup();
    370  await popupHiddenPromise;
    371 });
    372 
    373 // Navigation with a contenteditable body
    374 add_task(async function () {
    375  await BrowserTestUtils.openNewForegroundTab(gBrowser, testPage3);
    376 
    377  // The body should be focused when it is editable, not the root.
    378  gURLBar.focus();
    379  await expectFocusOnF6(
    380    false,
    381    "html3",
    382    "body3",
    383    true,
    384    "focus with contenteditable body"
    385  );
    386  await expectFocusOnF6(
    387    false,
    388    "main-window",
    389    gURLBar.inputField,
    390    false,
    391    "focus with contenteditable body urlbar"
    392  );
    393 
    394  // Now go backwards
    395 
    396  await expectFocusOnF6(
    397    false,
    398    "html3",
    399    "body3",
    400    true,
    401    "back focus with contenteditable body"
    402  );
    403  await expectFocusOnF6(
    404    false,
    405    "main-window",
    406    gURLBar.inputField,
    407    false,
    408    "back focus with contenteditable body urlbar"
    409  );
    410 
    411  BrowserTestUtils.removeTab(gBrowser.selectedTab);
    412 });
    413 
    414 // Navigation with a frameset loaded
    415 add_task(async function () {
    416  await BrowserTestUtils.openNewForegroundTab(
    417    gBrowser,
    418    "http://mochi.test:8888/browser/browser/base/content/test/general/file_documentnavigation_frameset.html"
    419  );
    420 
    421  gURLBar.focus();
    422  await expectFocusOnF6(
    423    false,
    424    "htmlframe1",
    425    "htmlframe1",
    426    true,
    427    "focus on frameset frame 0"
    428  );
    429  await expectFocusOnF6(
    430    false,
    431    "htmlframe2",
    432    "htmlframe2",
    433    true,
    434    "focus on frameset frame 1"
    435  );
    436  await expectFocusOnF6(
    437    false,
    438    "htmlframe3",
    439    "htmlframe3",
    440    true,
    441    "focus on frameset frame 2"
    442  );
    443  await expectFocusOnF6(
    444    false,
    445    "htmlframe4",
    446    "htmlframe4",
    447    true,
    448    "focus on frameset frame 3"
    449  );
    450  await expectFocusOnF6(
    451    false,
    452    "main-window",
    453    gURLBar.inputField,
    454    false,
    455    "focus on frameset frame urlbar"
    456  );
    457 
    458  await expectFocusOnF6(
    459    true,
    460    "htmlframe4",
    461    "htmlframe4",
    462    true,
    463    "back focus on frameset frame 3"
    464  );
    465  await expectFocusOnF6(
    466    true,
    467    "htmlframe3",
    468    "htmlframe3",
    469    true,
    470    "back focus on frameset frame 2"
    471  );
    472  await expectFocusOnF6(
    473    true,
    474    "htmlframe2",
    475    "htmlframe2",
    476    true,
    477    "back focus on frameset frame 1"
    478  );
    479  await expectFocusOnF6(
    480    true,
    481    "htmlframe1",
    482    "htmlframe1",
    483    true,
    484    "back focus on frameset frame 0"
    485  );
    486  await expectFocusOnF6(
    487    true,
    488    "main-window",
    489    gURLBar.inputField,
    490    false,
    491    "back focus on frameset frame urlbar"
    492  );
    493 
    494  BrowserTestUtils.removeTab(gBrowser.selectedTab);
    495 });
    496 
    497 // XXXndeakin add tests for browsers inside of panels
    498 
    499 function promiseButtonShown(id) {
    500  let dwu = window.windowUtils;
    501  return TestUtils.waitForCondition(() => {
    502    let target = document.getElementById(id);
    503    let bounds = dwu.getBoundsWithoutFlushing(target);
    504    return bounds.width > 0 && bounds.height > 0;
    505  }, `Waiting for button ${id} to have non-0 size`);
    506 }