Our indicator looks like this: an icon + a label.
The browser has an indicator for when a user is in private mode. The indicator lives in two places under different instances:
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.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.
- The "Shared" CSS file that controls the visibility of this icon
browser/themes/shared/browser-shared.css - 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;
}
}
}
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 browser tabs).
The image above shows that we are still in horizontal tabs
- When we have vertical tabs while still in private window, the
private-browsing-indicatorwill move to the navbar and then hide the label part of the indicator and keep only the icon.
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.mjsand 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 insideTabsToolbar, one insidenav-bar)How to toggle vertical tabs: by using the pref
sidebar.verticalTabsas seen here
SpecialPowers.pushPrefEnv({ set: [["sidebar.revamp", true], ["sidebar.verticalTabs", true]] })
Task structure:
add_task(async function () {...})Check visibility:
BrowserTestUtils.isVisible(element)How to open a private window (modern style):
BrowserTestUtils.openNewBrowserWindow({ private: true })
/* 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);
});
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:
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)
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],
],
});
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();
Test 3: Normal Browser Window
In this test, we turn off private browsing 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
-
test_indicator_horizontal_tabs: opens a private window in normal (default) tabs mode, checks the TabsToolbar copy is visible and the nav-bar copy is hidden. -
test_indicator_vertical_tabs: turns on vertical tabs mode, opens a private window, checks the opposite: nav-bar copy visible, TabsToolbar copy hidden. -
test_indicator_not_shown_in_normal_window: opens a completely normal, non-private window, and makes sure neither copy shows up at all, since this isn't a private window in the first place.
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
- 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



Top comments (0)