Incognito Implementation
This page provides a high level overview of how incognito works in Firefox, primarily to help in understanding how to test the feature.
The Implementation
The incognito value in manifest.json supports spanning
and not_allowed
.
The other value, split
, may be supported in the future. The default
value is spanning
, however, by default access to private windows is
not allowed. The user must turn on support, per extension, in about:addons
.
Internally this is handled as a hidden extension permission called
internal:privateBrowsingAllowed
. This permission is reset when the
extension is disabled or uninstalled. The permission is accessible in
several ways:
extension.privateBrowsingAllowed
context.privateBrowsingAllowed (see BaseContext)
WebExtensionPolicy.privateBrowsingAllowed
WebExtensionPolicy.canAccessWindow(DOMWindow)
Testing
The goal of testing is to ensure that data from a private browsing session is not accessible to an extension without permission.
In Firefox 67, the feature will initially be disabled, however the
intention is to enable the feature on in 67. The pref controlling this
is extensions.allowPrivateBrowsingByDefault
. When this pref is
true
, all extensions have access to private browsing and the manifest
value not_allowed
will produce an error. To enable incognito.not_allowed
for tests you must flip the pref to false.
Testing EventManager events
This is typically most easily handled by running a test with an extension
that has permission, using incognitoOverride: spanning
in the call to
ExtensionTestUtils.loadExtension. You can then use a second extension
without permission to try and catch any events that would typically be passed.
If the events can happen without calls produced by an extension, you can also use BrowserTestUtils to open a private window, and use a non-permissioned extension to run tests against it.
There are two utility functions in head.js, getIncognitoWindow and startIncognitoMonitorExtension, which are useful for some basic testing.
Example: browser_ext_windows_events.js
Testing API Calls
This is easily done using an extension without permission. If you need an ID of a window or tab, use getIncognitoWindow. In most cases, the API call should throw an exception when the window is not accessible. There are some cases where API calls explicitly do not throw.
Example: browser_ext_windows_incognito.js
Privateness of window vs. tab
Android does not currently support private windows. When a tab is available, the test should prefer tab over window.
PrivateBrowsingUtils.isBrowserPrivate(tab.linkedBrowser)
PrivateBrowsingUtils.isContentWindowPrivate(window)
When WebExtensionPolicy is handy to use, you can directly check window access:
policy.canAccessWindow(window)