Writing unit test for Firefox private browsing window

작성자

카테고리:

← 피드로
DEV Community · Ifeanyi Chima · 2026-07-06 개발(SW)
Cover image for Writing unit test for Firefox private browsing window

Ifeanyi Chima

Our indicator looks like this: an icon + a label.

private window indicator

The browser has an indicator for when a user is in private mode. The indicator lives in two places under different instances:

  1. The first instance is when the user is in “Horizontal Tabs” when the browser tabs are in the TabsToolbar (tab-bar or toolbar). So, the indicator shows both the icon and it’s label.

  2. The second instance is when the user has “Vertical Tabs” turned on. So, the indicator moves or shows up in the Navbar (which contains extensions, address bar) and this time only the icon shows up, no label.

Our task is to write a unit test to confirm that the icon shows up in both instance.

We start off by running this search grep -r "private-browsing-indicator-with-label" --include="*.xhtml" --include="*.js" --include="*.css" .

We found two things.

  1. The “Shared” CSS file that controls the visibility of this icon browser/themes/shared/browser-shared.css
  2. The browser/base/content/private-browsing-indicator.inc.xhtml — this is where the indicator’s actual markup (HTML-like structure) lives.

Now, we can check the CSS file for where it controls the visibility of the indicator by using this syntax grep -n -A 10 "private-browsing-indicator-with-label" browser/themes/shared/browser-shared.css

What we find out in the file:

.private-browsing-indicator-with-label {
  :root:not([privatebrowsingmode="temporary"]) &,
  #navigator-toolbox:not([tabs-hidden]) #nav-bar > & {
    display: none;
  }
  #navigator-toolbox[tabs-hidden] #nav-bar > & {
    margin-inline-end: var(--space-medium);
    > .private-browsing-indicator-label {
      display: none;
    }
  }
}

Enter fullscreen mode Exit fullscreen mode

What this means:

  • When the window isn’t a private window (we are in normal mode) – it will hide the indicator completely.

  • When we have horizontal tabs in private window, hide the indicator from the navbar (which contains extensions, address bar) and then the indicator will move to the TabsToolbar (which actually contains browser tabs).

Horizontal Tabs enabled

The image above shows that we are still in horizontal tabs

  • When we have vertical tabs while still in private window, the private-browsing-indicator will move to the navbar and then hide the label part of the indicator and keep only the icon.

Vertical Tab is enabled

The above image shows vertical tabs enabled

Writing the tests

Before we begin writing the tests, we would need to find other existing tests in the codebase to take inspiration from them, by using the search query:

grep -n "is_visible\|isVisible\|is_hidden\|isHidden" testing/mochitest/BrowserTestUtils/BrowserTestUtils.sys.mjs and then we read the file sed -n '325,350p' testing/mochitest/BrowserTestUtils/BrowserTestUtils.sys.mjs

This gives us a lot of information:

  • What to check: both copies of .private-browsing-indicator-with-label (one inside TabsToolbar, one inside nav-bar)

  • How to toggle vertical tabs: by using the pref sidebar.verticalTabs as seen here

SpecialPowers.pushPrefEnv({ set: [["sidebar.revamp", true], ["sidebar.verticalTabs", true]] })

Enter fullscreen mode Exit fullscreen mode

  • Task structure: add_task(async function () {...})

  • Check visibility: BrowserTestUtils.isVisible(element)

  • How to open a private window (modern style): BrowserTestUtils.openNewBrowserWindow({ private: true })

Now, we can write the tests as follows:


/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

"use strict";

// The private browsing indicator lives in two possible spots:
// - Inside #TabsToolbar (shown with icon + label, for horizontal tabs)
// - Inside #nav-bar (shown with icon only, for vertical tabs)
// This test makes sure at least one copy is always visible in a
// private window, no matter which tabs layout is active.

add_task(async function test_indicator_horizontal_tabs() {
  const win = await BrowserTestUtils.openNewBrowserWindow({ private: true });

  let tabsToolbarIndicator = win.document.querySelector(
    "#TabsToolbar .private-browsing-indicator-with-label"
  );
  let navBarIndicator = win.document.querySelector(
    "#nav-bar .private-browsing-indicator-with-label"
  );

  ok(
    BrowserTestUtils.isVisible(tabsToolbarIndicator),
    "Indicator should be visible in TabsToolbar with horizontal tabs"
  );
  ok(
    BrowserTestUtils.isHidden(navBarIndicator),
    "Indicator in nav-bar should be hidden with horizontal tabs"
  );

  await BrowserTestUtils.closeWindow(win);
});

add_task(async function test_indicator_vertical_tabs() {
  await SpecialPowers.pushPrefEnv({
    set: [
      ["sidebar.revamp", true],
      ["sidebar.verticalTabs", true],
    ],
  });

  const win = await BrowserTestUtils.openNewBrowserWindow({ private: true });

  let tabsToolbarIndicator = win.document.querySelector(
    "#TabsToolbar .private-browsing-indicator-with-label"
  );
  let navBarIndicator = win.document.querySelector(
    "#nav-bar .private-browsing-indicator-with-label"
  );

  ok(
    BrowserTestUtils.isHidden(tabsToolbarIndicator),
    "Indicator in TabsToolbar should be hidden with vertical tabs"
  );
  ok(
    BrowserTestUtils.isVisible(navBarIndicator),
    "Indicator should be visible in nav-bar with vertical tabs"
  );

  await BrowserTestUtils.closeWindow(win);
  await SpecialPowers.popPrefEnv();
});

add_task(async function test_indicator_not_shown_in_normal_window() {
  const win = await BrowserTestUtils.openNewBrowserWindow();

  let indicators = win.document.querySelectorAll(
    ".private-browsing-indicator-with-label"
  );

  for (let indicator of indicators) {
    ok(
      BrowserTestUtils.isHidden(indicator),
      "Indicator should never be visible in a normal (non-private) window"
    );
  }

  await BrowserTestUtils.closeWindow(win);
});

Enter fullscreen mode Exit fullscreen mode

Explaining the test:

Now, here is what this test is doing. Remember at the beginning, I said our private browsing lives in two possible spots:

  1. Inside #TabsToolbar (shown with icon + label, for horizontal tabs): This is when we have private browsing enabled, but we are still using horizontal browser tabs (the default)

  2. Inside #nav-bar (shown with icon only, for vertical tabs): This is when the user has enabled / turned on Vertical browser tabs.

Test 1: Horizontal Browser Tabs

The first test is saying open a private browser window using await BrowserTestUtils.openNewBrowserWindow({ private: true }); and then we are making sure that when we are in Horizontal Mode – the navbar indicator IS NOT showing. The only indicator that should be showing in Horizontal Mode is the tabsToolbarIndicator

Test 2: Vertical Browser Tabs

We open a private browser window using await BrowserTestUtils.openNewBrowserWindow({ private: true }); and now, we assume that the user has turned on vertical tabs, how do we do that in our test ?…. by using this pref to turn on vertical tabs during the test run

await SpecialPowers.pushPrefEnv({
    set: [
      ["sidebar.revamp", true],
      ["sidebar.verticalTabs", true],
    ],
  });

Enter fullscreen mode Exit fullscreen mode

Now, in Vertical Mode the only indicator that should show is the navBarIndicator and the other one should not show. Also, do not forget to close the browser window and cleanup the Pref using

await BrowserTestUtils.closeWindow(win);
await SpecialPowers.popPrefEnv();

Enter fullscreen mode Exit fullscreen mode

Test 3: Normal Browser Window

In this test, we open a normal browsing window and we make sure that none of those labels either navBarIndicator or tabsToolbarIndicator show up when the user is NOT using private browsing.

TLDR:

What each test does, briefly

  1. test_indicator_horizontal_tabs: opens a private window in normal (default) tabs mode, checks the TabsToolbar indicator is visible and the nav-bar indicator is hidden.
  2. test_indicator_vertical_tabs: opens a private window, turns on vertical tabs mode, check that the nav-bar indicator is visible, TabsToolbar indicator hidden.
  3. test_indicator_not_shown_in_normal_window: opens a completely normal (non-private window) and makes sure neither indicator shows up at all since this isn’t a private window in the first place.

Registering the test

In Firefox, whenever you write a test, you must register the test in browser.toml which is meant for that particular component – We are writing a test for the private browsing component; hence the file is located at browser/components/privatebrowsing/test/browser/browser.toml

Components are registered in an alphabetical order in this file.

["browser_privatebrowsing_favicon.js"]

["browser_privatebrowsing_history_shift_click.js"]

["browser_privatebrowsing_indicator.js"] # our unit test 

["browser_privatebrowsing_last_private_browsing_context_exited.js"]

["browser_privatebrowsing_lastpbcontextexited.js"]

["browser_privatebrowsing_localStorage.js"]

Enter fullscreen mode Exit fullscreen mode

SUMMARY:

When a user switches Firefox to private browsing mode, the indicator shows up, and the bug report was that there was never a unit test to ensure that the indicator is present in various browsing modes and so we wrote unit tests for those instances of the browser mode

  • Horizontal tabs mode (while private browsing is turned on)
  • Vertical tabs mode (while private browsing is turned on)
  • Normal browsing mode.

Find the Patch Here: https://phabricator.services.mozilla.com/D310523

Find the Bug Here: https://bugzilla.mozilla.org/show_bug.cgi?id=1927615

THANK YOU

원문에서 계속 ↗

코멘트

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다