mirror of
https://github.com/zen-browser/desktop.git
synced 2026-06-14 07:23:42 +00:00
chore: Sync upstream to Firefox 152.0
This commit is contained in:
committed by
github-actions[bot]
parent
d5cbe55d2b
commit
690fff1ca0
@@ -35,7 +35,7 @@ Zen is a firefox-based browser with the aim of pushing your productivity to a ne
|
||||
### Firefox Versions
|
||||
|
||||
- [`Release`](https://zen-browser.app/download) - Is currently built using Firefox version `151.0.4`! 🚀
|
||||
- [`Twilight`](https://zen-browser.app/download?twilight) - Is currently built using Firefox version `RC 151.0.4`!
|
||||
- [`Twilight`](https://zen-browser.app/download?twilight) - Is currently built using Firefox version `RC 152.0`!
|
||||
|
||||
### Contributing
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
9a6aa4c359d1fb6ac60decc82402f82d49a17cea
|
||||
a58ad2d2952face15859068dd4421cf68d6a9dda
|
||||
@@ -7,7 +7,7 @@ diff --git a/browser/base/content/main-popupset.inc.xhtml b/browser/base/content
|
||||
id="selection-shortcut-action-panel"
|
||||
noautofocus="true"
|
||||
consumeoutsideclicks="never"
|
||||
+ nonnativepopover="true"
|
||||
+ nonnative=""
|
||||
type="arrow">
|
||||
<hbox class="panel-subview-body">
|
||||
<html:moz-button id="ai-action-button"/>
|
||||
@@ -19,7 +19,7 @@ diff --git a/browser/base/content/main-popupset.inc.xhtml b/browser/base/content
|
||||
<panel class="panel-no-padding"
|
||||
id="chat-shortcuts-options-panel"
|
||||
noautofocus="true"
|
||||
+ nonnativepopover="true"
|
||||
+ nonnative=""
|
||||
type="arrow">
|
||||
<vbox class="panel-subview-body"/>
|
||||
</panel>
|
||||
@@ -31,7 +31,7 @@ diff --git a/browser/base/content/main-popupset.inc.xhtml b/browser/base/content
|
||||
noautofocus="true"
|
||||
norolluponanchor="true"
|
||||
consumeoutsideclicks="false"
|
||||
+ nonnativepopover="true"
|
||||
+ nonnative=""
|
||||
role="tooltip">
|
||||
<html:div class="tab-preview-content-interactive"></html:div>
|
||||
<html:div class="tab-preview-content-main">
|
||||
@@ -46,7 +46,7 @@ diff --git a/browser/components/asrouter/modules/FeatureCallout.sys.mjs b/browse
|
||||
type="arrow"
|
||||
consumeoutsideclicks="never"
|
||||
norolluponanchor="true"
|
||||
+
|
||||
+ nonnative=""
|
||||
position="${panel_position.panel_position_string}"
|
||||
${hide_arrow ? "" : 'show-arrow=""'}
|
||||
${autohide ? "" : 'noautohide="true"'}
|
||||
@@ -61,7 +61,7 @@ diff --git a/browser/components/customizableui/content/panelUI.inc.xhtml b/brows
|
||||
hidden="true"
|
||||
flip="slide"
|
||||
position="bottomright topright"
|
||||
+ hidepopovertail="true"
|
||||
+ hidepopovertail=""
|
||||
noautofocus="true">
|
||||
<panelmultiview id="appMenu-multiView" mainViewId="appMenu-mainView"
|
||||
viewCacheId="appMenu-viewCache">
|
||||
@@ -70,31 +70,33 @@ diff --git a/browser/components/customizableui/content/panelUI.inc.xhtml b/brows
|
||||
diff --git a/dom/xul/XULPopupElement.cpp b/dom/xul/XULPopupElement.cpp
|
||||
--- a/dom/xul/XULPopupElement.cpp
|
||||
+++ b/dom/xul/XULPopupElement.cpp
|
||||
@@ -80,10 +80,14 @@
|
||||
@@ -80,10 +80,15 @@
|
||||
}
|
||||
|
||||
void XULPopupElement::OpenPopupAtScreen(int32_t aXPos, int32_t aYPos,
|
||||
bool aIsContextMenu,
|
||||
Event* aTriggerEvent) {
|
||||
+ // TODO(cheff): At nsCocoaWindow::Show but we check for ShouldShowAsNSPopover
|
||||
+ // to determine whether to use a native popover or not. This should sort of
|
||||
+ // "replicate" that logic here, but it's a bit of a hacky way.
|
||||
+ SetAttr(kNameSpaceID_None, nsGkAtoms::nonnativepopover, u"true"_ns, true);
|
||||
+ if (NodeInfo()->NameAtom() == nsGkAtoms::panel) {
|
||||
+ // TODO(bug 2038354): Remove this and make the front-end set the attribute
|
||||
+ // explicitly.
|
||||
+ SetAttr(kNameSpaceID_None, nsGkAtoms::nonnative, u"true"_ns, true);
|
||||
+ }
|
||||
nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
|
||||
if (pm) {
|
||||
pm->ShowPopupAtScreen(this, aXPos, aYPos, aIsContextMenu, aTriggerEvent);
|
||||
}
|
||||
}
|
||||
@@ -93,10 +97,14 @@
|
||||
@@ -93,10 +98,15 @@
|
||||
int32_t aWidth, int32_t aHeight,
|
||||
bool aIsContextMenu,
|
||||
bool aAttributesOverride,
|
||||
Event* aTriggerEvent) {
|
||||
nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
|
||||
+ // TODO: See OpenPopupAtScreen. We should remove this and use the other
|
||||
+ // implementation because this is a bit of a hacky way to determine whether to
|
||||
+ // use a native popover or not.
|
||||
+ SetAttr(kNameSpaceID_None, nsGkAtoms::nonnativepopover, u"true"_ns, true);
|
||||
+ if (NodeInfo()->NameAtom() == nsGkAtoms::panel) {
|
||||
+ // TODO(bug 2038354): Remove this and make the front-end set the attribute
|
||||
+ // explicitly.
|
||||
+ SetAttr(kNameSpaceID_None, nsGkAtoms::nonnative, u"true"_ns, true);
|
||||
+ }
|
||||
if (pm) {
|
||||
pm->ShowPopupAtScreenRect(
|
||||
this, aPosition, nsIntRect(aXPos, aYPos, aWidth, aHeight),
|
||||
@@ -103,7 +105,7 @@ diff --git a/dom/xul/XULPopupElement.cpp b/dom/xul/XULPopupElement.cpp
|
||||
diff --git a/layout/xul/nsMenuPopupFrame.h b/layout/xul/nsMenuPopupFrame.h
|
||||
--- a/layout/xul/nsMenuPopupFrame.h
|
||||
+++ b/layout/xul/nsMenuPopupFrame.h
|
||||
@@ -528,18 +528,10 @@
|
||||
@@ -516,18 +516,10 @@
|
||||
|
||||
// Move the popup to the position specified in its |left| and |top|
|
||||
// attributes.
|
||||
@@ -122,7 +124,7 @@ diff --git a/layout/xul/nsMenuPopupFrame.h b/layout/xul/nsMenuPopupFrame.h
|
||||
public:
|
||||
/**
|
||||
* Return whether the popup direction should be RTL.
|
||||
@@ -548,10 +540,18 @@
|
||||
@@ -536,10 +528,18 @@
|
||||
*
|
||||
* Return whether the popup direction should be RTL.
|
||||
*/
|
||||
@@ -144,7 +146,7 @@ diff --git a/layout/xul/nsMenuPopupFrame.h b/layout/xul/nsMenuPopupFrame.h
|
||||
diff --git a/modules/libpref/init/StaticPrefList.yaml b/modules/libpref/init/StaticPrefList.yaml
|
||||
--- a/modules/libpref/init/StaticPrefList.yaml
|
||||
+++ b/modules/libpref/init/StaticPrefList.yaml
|
||||
@@ -19672,10 +19672,19 @@
|
||||
@@ -19840,10 +19840,19 @@
|
||||
value: true
|
||||
mirror: always
|
||||
|
||||
@@ -168,20 +170,20 @@ diff --git a/toolkit/themes/shared/global-shared.css b/toolkit/themes/shared/glo
|
||||
--- a/toolkit/themes/shared/global-shared.css
|
||||
+++ b/toolkit/themes/shared/global-shared.css
|
||||
@@ -72,10 +72,22 @@
|
||||
--menuitem-border-radius: var(--panel-menuitem-border-radius);
|
||||
--menuitem-padding: var(--panel-menuitem-padding);
|
||||
--menuitem-margin: var(--panel-menuitem-margin);
|
||||
--menuitem-border-radius: var(--arrowpanel-menuitem-border-radius);
|
||||
--menuitem-padding: var(--arrowpanel-menuitem-padding);
|
||||
--menuitem-margin: var(--arrowpanel-menuitem-margin);
|
||||
}
|
||||
|
||||
+/* stylelint-disable-next-line media-query-no-invalid */
|
||||
+@media -moz-pref("widget.macos.native-popovers") and (-moz-platform: macos) {
|
||||
+ panel:not(:where([nonnativepopover="true"])) {
|
||||
+ panel:not([nonnative]) {
|
||||
+ background-color: transparent;
|
||||
+ --panel-background: transparent;
|
||||
+ --panel-shadow: none;
|
||||
+ --panel-box-shadow: none;
|
||||
+ --panel-border-color: transparent;
|
||||
+ --panel-shadow-margin: 0px;
|
||||
+
|
||||
+ --panel-box-shadow-margin: 0px;
|
||||
+ --panel-padding: 0px;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
@@ -241,7 +243,7 @@ diff --git a/widget/cocoa/nsCocoaWindow.h b/widget/cocoa/nsCocoaWindow.h
|
||||
|
||||
+ // Check if this window should use NSPopover for popup/menu display
|
||||
+ bool ShouldUseNSPopover() const;
|
||||
+ bool ShouldShowAsNSPopover() const override;
|
||||
+ bool ShouldShowAsNSPopover() const;
|
||||
+
|
||||
[[nodiscard]] nsresult Create(nsIWidget* aParent, const DesktopIntRect& aRect,
|
||||
const InitData&) override;
|
||||
@@ -265,7 +267,7 @@ diff --git a/widget/cocoa/nsCocoaWindow.mm b/widget/cocoa/nsCocoaWindow.mm
|
||||
#include "nsIDOMWindowUtils.h"
|
||||
#include "nsILocalFileMac.h"
|
||||
#include "CocoaCompositorWidget.h"
|
||||
@@ -5031,10 +5034,15 @@
|
||||
@@ -5088,10 +5091,15 @@
|
||||
if (mWindowType == WindowType::Popup) {
|
||||
SetPopupWindowLevel();
|
||||
mWindow.backgroundColor = NSColor.clearColor;
|
||||
@@ -281,7 +283,7 @@ diff --git a/widget/cocoa/nsCocoaWindow.mm b/widget/cocoa/nsCocoaWindow.mm
|
||||
// the active space. Does not work with multiple displays. See
|
||||
// NeedsRecreateToReshow() for multi-display with multi-space workaround.
|
||||
mWindow.collectionBehavior = mWindow.collectionBehavior |
|
||||
@@ -5236,10 +5244,57 @@
|
||||
@@ -5293,10 +5301,57 @@
|
||||
NS_OBJC_END_TRY_IGNORE_BLOCK;
|
||||
}
|
||||
|
||||
@@ -339,7 +341,7 @@ diff --git a/widget/cocoa/nsCocoaWindow.mm b/widget/cocoa/nsCocoaWindow.mm
|
||||
NS_OBJC_BEGIN_TRY_IGNORE_BLOCK;
|
||||
|
||||
if (!mWindow) {
|
||||
@@ -5300,10 +5355,58 @@
|
||||
@@ -5357,10 +5412,53 @@
|
||||
mWindow.contentView.needsDisplay = YES;
|
||||
if (!nativeParentWindow || mPopupLevel != PopupLevel::Parent) {
|
||||
[mWindow orderFront:nil];
|
||||
@@ -375,22 +377,17 @@ diff --git a/widget/cocoa/nsCocoaWindow.mm b/widget/cocoa/nsCocoaWindow.mm
|
||||
+ // specific parent view
|
||||
+ NSRect positioningRect = [parentView convertRect:windowRect
|
||||
+ fromView:nil];
|
||||
+ BOOL shouldHideAnchor = NO;
|
||||
+ auto& element = popupFrame->PopupElement();
|
||||
+ if (element.GetBoolAttr(nsGkAtoms::hidepopovertail)) {
|
||||
+ shouldHideAnchor = YES;
|
||||
+ }
|
||||
+ bool shouldHideAnchor =
|
||||
+ popupFrame->PopupElement().GetBoolAttr(nsGkAtoms::hidepopovertail);
|
||||
+ [(PopupWindow*)mWindow showPopoverRelativeToRect:positioningRect
|
||||
+ ofView:parentView
|
||||
+ preferredEdge:preferredEdge
|
||||
+ hiddenAnchor:shouldHideAnchor];
|
||||
+#pragma clang diagnostic push
|
||||
+#pragma clang diagnostic ignored "-Wobjc-method-access"
|
||||
+ SyncPopoverBounds([(PopupWindow*)mWindow popover], popupFrame);
|
||||
+
|
||||
+
|
||||
+
|
||||
+
|
||||
+#pragma clang diagnostic pop
|
||||
+ // Exit early here since the popover is now shown.
|
||||
+
|
||||
+ return;
|
||||
+ }
|
||||
// If our popup window is a non-native context menu, tell the OS (and
|
||||
@@ -398,7 +395,7 @@ diff --git a/widget/cocoa/nsCocoaWindow.mm b/widget/cocoa/nsCocoaWindow.mm
|
||||
// close other programs' context menus when ours open.
|
||||
if ([mWindow isKindOfClass:[PopupWindow class]] &&
|
||||
[(PopupWindow*)mWindow isContextMenu]) {
|
||||
@@ -5373,11 +5476,15 @@
|
||||
@@ -5430,11 +5528,15 @@
|
||||
// unhook it here before ordering it out. When you order out the child
|
||||
// of a window it hides the parent window.
|
||||
if (mWindowType == WindowType::Popup && nativeParentWindow) {
|
||||
@@ -415,7 +412,7 @@ diff --git a/widget/cocoa/nsCocoaWindow.mm b/widget/cocoa/nsCocoaWindow.mm
|
||||
// other programs) that a menu has closed.
|
||||
if ([mWindow isKindOfClass:[PopupWindow class]] &&
|
||||
[(PopupWindow*)mWindow isContextMenu]) {
|
||||
@@ -5424,10 +5531,28 @@
|
||||
@@ -5481,10 +5583,28 @@
|
||||
return false;
|
||||
}
|
||||
return nsIWidget::ShouldUseOffMainThreadCompositing();
|
||||
@@ -424,8 +421,8 @@ diff --git a/widget/cocoa/nsCocoaWindow.mm b/widget/cocoa/nsCocoaWindow.mm
|
||||
+bool nsCocoaWindow::ShouldUseNSPopover() const {
|
||||
+ // Use NSPopover for panel popups when the preference is enabled
|
||||
+ // But not for detached popups - they should use traditional window logic
|
||||
+ return (mWindowType == WindowType::Popup && mPopupType == PopupType::Panel &&
|
||||
+ mozilla::StaticPrefs::widget_macos_native_popovers());
|
||||
+ return mWindowType == WindowType::Popup && mPopupType == PopupType::Panel &&
|
||||
+ mozilla::StaticPrefs::widget_macos_native_popovers();
|
||||
+}
|
||||
+
|
||||
+bool nsCocoaWindow::ShouldShowAsNSPopover() const {
|
||||
@@ -444,7 +441,7 @@ diff --git a/widget/cocoa/nsCocoaWindow.mm b/widget/cocoa/nsCocoaWindow.mm
|
||||
|
||||
return mWindow.isOpaque ? TransparencyMode::Opaque
|
||||
: TransparencyMode::Transparent;
|
||||
@@ -6378,10 +6503,19 @@
|
||||
@@ -6442,10 +6562,22 @@
|
||||
|
||||
// We ignore aRepaint -- we have to call display:YES, otherwise the
|
||||
// title bar doesn't immediately get repainted and is displayed in
|
||||
@@ -454,17 +451,20 @@ diff --git a/widget/cocoa/nsCocoaWindow.mm b/widget/cocoa/nsCocoaWindow.mm
|
||||
+ [(PopupWindow*)mWindow updatePopoverContent];
|
||||
+ // A popover won't resize by setting the frame
|
||||
+ // as it's size is calculated based on the content size
|
||||
+ // Therefor the content size has to be changed as well
|
||||
+ // Therefore the content size has to be changed as well
|
||||
+ NSSize contentSize = NSMakeSize(aWidth, aHeight);
|
||||
+#pragma clang diagnostic push
|
||||
+#pragma clang diagnostic ignored "-Wobjc-method-access"
|
||||
+ [[(PopupWindow*)mWindow popover] setContentSize:contentSize];
|
||||
+ SyncPopoverBounds([(PopupWindow*)mWindow popover], GetPopupFrame());
|
||||
+#pragma clang diagnostic pop
|
||||
+ }
|
||||
|
||||
NS_OBJC_END_TRY_IGNORE_BLOCK;
|
||||
}
|
||||
|
||||
void nsCocoaWindow::Resize(const DesktopRect& aRect, bool aRepaint) {
|
||||
@@ -8393,18 +8527,31 @@
|
||||
@@ -8517,18 +8649,31 @@
|
||||
backing:bufferingType
|
||||
defer:deferCreation];
|
||||
if (!self) {
|
||||
@@ -497,7 +497,7 @@ diff --git a/widget/cocoa/nsCocoaWindow.mm b/widget/cocoa/nsCocoaWindow.mm
|
||||
// Return 0 in order to match what the system does for sheet windows and
|
||||
// _NSPopoverWindows.
|
||||
- (CGFloat)_backdropBleedAmount {
|
||||
@@ -8460,10 +8607,122 @@
|
||||
@@ -8584,10 +8729,125 @@
|
||||
|
||||
- (void)setIsContextMenu:(BOOL)flag {
|
||||
mIsContextMenu = flag;
|
||||
@@ -537,7 +537,7 @@ diff --git a/widget/cocoa/nsCocoaWindow.mm b/widget/cocoa/nsCocoaWindow.mm
|
||||
+}
|
||||
+
|
||||
+- (BOOL)usePopover {
|
||||
+ return mUsePopover && !mIsContextMenu;
|
||||
+ return mUsePopover;
|
||||
+}
|
||||
+
|
||||
+- (void)showPopoverRelativeToRect:(NSRect)positioningRect
|
||||
@@ -562,7 +562,10 @@ diff --git a/widget/cocoa/nsCocoaWindow.mm b/widget/cocoa/nsCocoaWindow.mm
|
||||
+
|
||||
+ // This is a hidden API that prevents the popover from showing its arrow
|
||||
+ // pointing to the anchor.
|
||||
+#pragma clang diagnostic push
|
||||
+#pragma clang diagnostic ignored "-Wobjc-method-access"
|
||||
+ [mPopover setShouldHideAnchor:hiddenAnchor];
|
||||
+#pragma clang diagnostic pop
|
||||
+
|
||||
+ [mPopover showRelativeToRect:positioningRect
|
||||
+ ofView:positioningView
|
||||
@@ -620,25 +623,6 @@ diff --git a/widget/cocoa/nsCocoaWindow.mm b/widget/cocoa/nsCocoaWindow.mm
|
||||
return NO;
|
||||
}
|
||||
|
||||
diff --git a/widget/nsIWidget.h b/widget/nsIWidget.h
|
||||
--- a/widget/nsIWidget.h
|
||||
+++ b/widget/nsIWidget.h
|
||||
@@ -829,10 +829,15 @@
|
||||
virtual void SuppressAnimation(bool aSuppress) {}
|
||||
|
||||
/** Sets windows-specific mica backdrop on this widget. */
|
||||
virtual void SetMicaBackdrop(bool) {}
|
||||
|
||||
+ /**
|
||||
+ * Determine whether this widget should be shown as an NSPopover.
|
||||
+ */
|
||||
+ virtual bool ShouldShowAsNSPopover() const { return false; }
|
||||
+
|
||||
/**
|
||||
* Return size mode (minimized, maximized, normalized).
|
||||
* Returns a value from nsSizeMode (see nsIWidgetListener.h)
|
||||
*/
|
||||
virtual nsSizeMode SizeMode() = 0;
|
||||
diff --git a/xpcom/ds/StaticAtoms.py b/xpcom/ds/StaticAtoms.py
|
||||
--- a/xpcom/ds/StaticAtoms.py
|
||||
+++ b/xpcom/ds/StaticAtoms.py
|
||||
@@ -654,16 +638,4 @@ diff --git a/xpcom/ds/StaticAtoms.py b/xpcom/ds/StaticAtoms.py
|
||||
Atom("highest", "highest"),
|
||||
Atom("horizontal", "horizontal"),
|
||||
Atom("hover", "hover"),
|
||||
@@ -759,10 +760,11 @@
|
||||
Atom("nohref", "nohref"),
|
||||
Atom("noinitialselection", "noinitialselection"),
|
||||
Atom("nomodule", "nomodule"),
|
||||
Atom("nonce", "nonce"),
|
||||
Atom("none", "none"),
|
||||
+ Atom("nonnativepopover", "nonnativepopover"),
|
||||
Atom("noresize", "noresize"),
|
||||
Atom("normal", "normal"),
|
||||
Atom("normalizeSpace", "normalize-space"),
|
||||
Atom("noscript", "noscript"),
|
||||
Atom("noshade", "noshade"),
|
||||
|
||||
|
||||
@@ -1,3 +1,18 @@
|
||||
diff --git a/toolkit/themes/shared/global-shared.css b/toolkit/themes/shared/global-shared.css
|
||||
--- a/toolkit/themes/shared/global-shared.css
|
||||
+++ b/toolkit/themes/shared/global-shared.css
|
||||
@@ -80,11 +80,10 @@
|
||||
background-color: transparent;
|
||||
--panel-background: transparent;
|
||||
--panel-box-shadow: none;
|
||||
--panel-border-color: transparent;
|
||||
--panel-box-shadow-margin: 0px;
|
||||
- --panel-padding: 0px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Lightweight theme roots */
|
||||
|
||||
diff --git a/widget/cocoa/nsCocoaWindow.h b/widget/cocoa/nsCocoaWindow.h
|
||||
--- a/widget/cocoa/nsCocoaWindow.h
|
||||
+++ b/widget/cocoa/nsCocoaWindow.h
|
||||
|
||||
@@ -40,7 +40,7 @@ add_task(async function testNormalBrowsing() {
|
||||
browser: tab.linkedBrowser,
|
||||
uriString: TEST_PAGE,
|
||||
});
|
||||
testWhitelistedPage(tab.ownerGlobal);
|
||||
testWhitelistedPage(tab.documentGlobal);
|
||||
|
||||
info("Load a test page that's no longer whitelisted");
|
||||
Services.prefs.setCharPref(PREF_WHITELISTED_HOSTNAMES, "");
|
||||
@@ -54,5 +54,5 @@ add_task(async function testNormalBrowsing() {
|
||||
);
|
||||
BrowserTestUtils.startLoadingURIString(tab.linkedBrowser, TEST_PAGE);
|
||||
await blockedLoaded;
|
||||
testBlockedPage(tab.ownerGlobal);
|
||||
testBlockedPage(tab.documentGlobal);
|
||||
});
|
||||
|
||||
@@ -2,7 +2,10 @@
|
||||
|
||||
["browser_1119088.js"]
|
||||
disabled="Disabled by import_external_tests.py"
|
||||
support-files = ["mac_desktop_image.py"]
|
||||
support-files = [
|
||||
"large.png",
|
||||
"mac_desktop_image.py"
|
||||
]
|
||||
run-if = [
|
||||
"os == 'mac'",
|
||||
]
|
||||
@@ -12,6 +15,7 @@ skip-if = [
|
||||
]
|
||||
|
||||
["browser_420786.js"]
|
||||
support-files = ["large.png"]
|
||||
run-if = [
|
||||
"os == 'linux' && os_version == '22.04' && arch == 'x86_64' && display == 'wayland'",
|
||||
"os == 'linux' && os_version == '24.04' && arch == 'x86_64' && display == 'x11'",
|
||||
@@ -116,4 +120,5 @@ tags = "os_integration"
|
||||
|
||||
["browser_setDesktopBackgroundPreview.js"]
|
||||
disabled="Disabled by import_external_tests.py"
|
||||
support-files = ["large.png"]
|
||||
tags = "os_integration"
|
||||
|
||||
@@ -92,20 +92,19 @@ add_setup(async function () {
|
||||
/**
|
||||
* Tests "Set As Desktop Background" platform implementation on macOS.
|
||||
*
|
||||
* Sets the desktop background image to the browser logo from the about:logo
|
||||
* page and verifies it was set successfully. Setting the desktop background
|
||||
* (which uses the nsIShellService::setDesktopBackground() interface method)
|
||||
* downloads the image to ~/Pictures using a unique file name and sets the
|
||||
* desktop background to the downloaded file leaving the download in place.
|
||||
* After setDesktopBackground() is called, the test uses a python script to
|
||||
* validate that the current desktop background is in fact set to the
|
||||
* downloaded logo.
|
||||
* Sets the desktop background image to the large.png image and verifies it was
|
||||
* set successfully. Setting the desktop background (which uses the
|
||||
* nsIShellService::setDesktopBackground() interface method) downloads the
|
||||
* image to ~/Pictures using a unique file name and sets the desktop background
|
||||
* to the downloaded file leaving the download in place. After
|
||||
* setDesktopBackground() is called, the test uses a python script to validate
|
||||
* that the current desktop background is in fact set to the downloaded image.
|
||||
*/
|
||||
add_task(async function () {
|
||||
await BrowserTestUtils.withNewTab(
|
||||
{
|
||||
gBrowser,
|
||||
url: "about:logo",
|
||||
url: getRootDirectory(gTestPath) + "large.png",
|
||||
},
|
||||
async () => {
|
||||
let dirSvc = Cc["@mozilla.org/file/directory_service;1"].getService(
|
||||
@@ -140,7 +139,7 @@ add_task(async function () {
|
||||
|
||||
// For simplicity, we're going to reach in and access the image on the
|
||||
// page directly, which means the page shouldn't be running in a remote
|
||||
// browser. Thankfully, about:logo runs in the parent process for now.
|
||||
// browser. Thankfully, chrome:// runs in the parent process for now.
|
||||
Assert.ok(
|
||||
!gBrowser.selectedBrowser.isRemoteBrowser,
|
||||
"image can be accessed synchronously from the parent process"
|
||||
|
||||
@@ -12,7 +12,7 @@ add_task(async function () {
|
||||
await BrowserTestUtils.withNewTab(
|
||||
{
|
||||
gBrowser,
|
||||
url: "about:logo",
|
||||
url: getRootDirectory(gTestPath) + "large.png",
|
||||
},
|
||||
() => {
|
||||
var brandName = Services.strings
|
||||
@@ -46,7 +46,7 @@ add_task(async function () {
|
||||
|
||||
// For simplicity, we're going to reach in and access the image on the
|
||||
// page directly, which means the page shouldn't be running in a remote
|
||||
// browser. Thankfully, about:logo runs in the parent process for now.
|
||||
// browser. Thankfully, chrome:// runs in the parent process for now.
|
||||
Assert.ok(
|
||||
!gBrowser.selectedBrowser.isRemoteBrowser,
|
||||
"image can be accessed synchronously from the parent process"
|
||||
|
||||
@@ -323,14 +323,39 @@ add_task(async function test_setAsDefaultPDFHandler_knownBrowser() {
|
||||
}
|
||||
});
|
||||
|
||||
// Wait for the deferred set_default_pdf_handler_attempt event to be recorded,
|
||||
// then return the single event that was emitted by the most recent call.
|
||||
async function awaitAttemptEvent() {
|
||||
await TestUtils.waitForCondition(() => {
|
||||
const events = Glean.browser.setDefaultPdfHandlerAttempt.testGetValue();
|
||||
return events && events.length;
|
||||
}, "Recorded set_default_pdf_handler_attempt event");
|
||||
const events = Glean.browser.setDefaultPdfHandlerAttempt.testGetValue();
|
||||
Assert.equal(events.length, 1, "Recorded exactly one attempt event");
|
||||
return events[0];
|
||||
}
|
||||
|
||||
add_task(async function test_setAsDefaultPDFHandler_fallback() {
|
||||
const sandbox = sinon.createSandbox();
|
||||
// Enable the IOpenWithLauncher branch explicitly so the test does not
|
||||
// depend on the build-channel default of
|
||||
// browser.shell.setDefaultPDFHandler.useOpenWith, and use a 0ms wait so
|
||||
// the deferred attempt event fires promptly.
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
["browser.shell.setDefaultPDFHandler.useOpenWith", true],
|
||||
["browser.shell.setDefaultPDFHandler.attemptWaitTimeMs", 0],
|
||||
],
|
||||
});
|
||||
|
||||
try {
|
||||
const userChoiceStub = sandbox
|
||||
.stub(ShellService, "setAsDefaultPDFHandlerUserChoice")
|
||||
.rejects(new Error("mock userChoice failure"));
|
||||
sandbox.stub(ShellService, "_isWindows11").returns(true);
|
||||
const isDefaultHandlerForStub = sandbox
|
||||
.stub(ShellService, "isDefaultHandlerFor")
|
||||
.returns(true);
|
||||
|
||||
info(
|
||||
"When userChoice fails and open-with picker succeeds, should not fall back to settings dialog"
|
||||
@@ -352,27 +377,42 @@ add_task(async function test_setAsDefaultPDFHandler_fallback() {
|
||||
1,
|
||||
"Recorded user-choice failure"
|
||||
);
|
||||
|
||||
let event = await awaitAttemptEvent();
|
||||
Assert.equal(event.extra.method, "open_with", "Event method is open_with");
|
||||
Assert.equal(event.extra.success, "true", "Event success is true");
|
||||
Assert.equal(
|
||||
Glean.browser.setDefaultPdfHandlerUserChoiceResult.Success.testGetValue(),
|
||||
undefined,
|
||||
"Did not record user-choice success"
|
||||
event.extra.result_is_default,
|
||||
"true",
|
||||
"Event result_is_default reflects isDefaultHandlerFor"
|
||||
);
|
||||
Assert.equal(
|
||||
Glean.browser.setDefaultPdfHandlerOpenWithResult.Success.testGetValue(),
|
||||
1,
|
||||
"Recorded open-with success"
|
||||
);
|
||||
Assert.equal(
|
||||
Glean.browser.setDefaultPdfHandlerOpenWithResult.Failure.testGetValue(),
|
||||
undefined,
|
||||
"Did not record open-with failure"
|
||||
);
|
||||
Assert.equal(
|
||||
Glean.browser.setDefaultPdfHandlerModernSettingsResult.Success.testGetValue(),
|
||||
undefined,
|
||||
"Did not record modern settings result"
|
||||
Assert.ok(
|
||||
isDefaultHandlerForStub.calledWith(".pdf"),
|
||||
"Sampled isDefaultHandlerFor after the delay"
|
||||
);
|
||||
userChoiceStub.resetHistory();
|
||||
isDefaultHandlerForStub.resetHistory();
|
||||
launchOpenWithDefaultPickerForFileTypeStub.resetHistory();
|
||||
launchModernSettingsDialogDefaultAppsStub.resetHistory();
|
||||
|
||||
info(
|
||||
"When the picker succeeds but Firefox is not default after the delay, event records result_is_default=false"
|
||||
);
|
||||
Services.fog.testResetFOG();
|
||||
isDefaultHandlerForStub.returns(false);
|
||||
await ShellService.setAsDefaultPDFHandler(false);
|
||||
|
||||
event = await awaitAttemptEvent();
|
||||
Assert.equal(event.extra.method, "open_with", "Event method is open_with");
|
||||
Assert.equal(event.extra.success, "true", "Event success is true");
|
||||
Assert.equal(
|
||||
event.extra.result_is_default,
|
||||
"false",
|
||||
"Event result_is_default is false when Firefox did not become default"
|
||||
);
|
||||
isDefaultHandlerForStub.returns(true);
|
||||
userChoiceStub.resetHistory();
|
||||
isDefaultHandlerForStub.resetHistory();
|
||||
launchOpenWithDefaultPickerForFileTypeStub.resetHistory();
|
||||
launchModernSettingsDialogDefaultAppsStub.resetHistory();
|
||||
|
||||
@@ -399,72 +439,120 @@ add_task(async function test_setAsDefaultPDFHandler_fallback() {
|
||||
1,
|
||||
"Recorded user-choice failure"
|
||||
);
|
||||
Assert.equal(
|
||||
Glean.browser.setDefaultPdfHandlerUserChoiceResult.Success.testGetValue(),
|
||||
undefined,
|
||||
"Did not record user-choice success"
|
||||
);
|
||||
Assert.equal(
|
||||
Glean.browser.setDefaultPdfHandlerOpenWithResult.Failure.testGetValue(),
|
||||
1,
|
||||
"Recorded open-with failure"
|
||||
);
|
||||
Assert.equal(
|
||||
Glean.browser.setDefaultPdfHandlerOpenWithResult.Success.testGetValue(),
|
||||
undefined,
|
||||
"Did not record open-with success"
|
||||
);
|
||||
Assert.equal(
|
||||
Glean.browser.setDefaultPdfHandlerModernSettingsResult.Success.testGetValue(),
|
||||
1,
|
||||
"Recorded modern settings success"
|
||||
);
|
||||
|
||||
event = await awaitAttemptEvent();
|
||||
Assert.equal(
|
||||
Glean.browser.setDefaultPdfHandlerModernSettingsResult.Failure.testGetValue(),
|
||||
undefined,
|
||||
"Did not record modern settings failure"
|
||||
event.extra.method,
|
||||
"settings",
|
||||
"Event method is settings (last attempted)"
|
||||
);
|
||||
Assert.equal(
|
||||
event.extra.success,
|
||||
"true",
|
||||
"Event success reflects modern settings launch"
|
||||
);
|
||||
Assert.equal(
|
||||
event.extra.result_is_default,
|
||||
"true",
|
||||
"Event result_is_default reflects isDefaultHandlerFor"
|
||||
);
|
||||
userChoiceStub.resetHistory();
|
||||
isDefaultHandlerForStub.resetHistory();
|
||||
launchOpenWithDefaultPickerForFileTypeStub.resetHistory();
|
||||
launchModernSettingsDialogDefaultAppsStub.resetHistory();
|
||||
|
||||
info(
|
||||
"When userChoice fails, open-with fails, and modern settings fails, should record all failures"
|
||||
"When userChoice fails, open-with fails, and modern settings fails, event records success=false"
|
||||
);
|
||||
Services.fog.testResetFOG();
|
||||
isDefaultHandlerForStub.returns(false);
|
||||
launchModernSettingsDialogDefaultAppsStub.throws(
|
||||
new Error("mock modern settings failure")
|
||||
);
|
||||
await ShellService.setAsDefaultPDFHandler(false);
|
||||
|
||||
Assert.equal(
|
||||
Glean.browser.setDefaultPdfHandlerUserChoiceResult.ErrOther.testGetValue(),
|
||||
1,
|
||||
"Recorded user-choice failure"
|
||||
);
|
||||
Assert.equal(
|
||||
Glean.browser.setDefaultPdfHandlerUserChoiceResult.Success.testGetValue(),
|
||||
undefined,
|
||||
"Did not record user-choice success"
|
||||
);
|
||||
Assert.equal(
|
||||
Glean.browser.setDefaultPdfHandlerOpenWithResult.Failure.testGetValue(),
|
||||
1,
|
||||
"Recorded open-with failure"
|
||||
);
|
||||
Assert.equal(
|
||||
Glean.browser.setDefaultPdfHandlerModernSettingsResult.Failure.testGetValue(),
|
||||
1,
|
||||
"Recorded modern settings failure"
|
||||
);
|
||||
|
||||
event = await awaitAttemptEvent();
|
||||
Assert.equal(
|
||||
Glean.browser.setDefaultPdfHandlerModernSettingsResult.Success.testGetValue(),
|
||||
undefined,
|
||||
"Did not record modern settings success"
|
||||
event.extra.method,
|
||||
"settings",
|
||||
"Event method is settings (last attempted)"
|
||||
);
|
||||
Assert.equal(
|
||||
event.extra.success,
|
||||
"false",
|
||||
"Event success is false when every method failed"
|
||||
);
|
||||
Assert.equal(
|
||||
event.extra.result_is_default,
|
||||
"false",
|
||||
"Event result_is_default is false when no method set the default"
|
||||
);
|
||||
} finally {
|
||||
launchOpenWithDefaultPickerForFileTypeStub.reset();
|
||||
launchModernSettingsDialogDefaultAppsStub.reset();
|
||||
sandbox.restore();
|
||||
await SpecialPowers.popPrefEnv();
|
||||
}
|
||||
});
|
||||
|
||||
add_task(async function test_setAsDefaultPDFHandler_useOpenWithDisabled() {
|
||||
const sandbox = sinon.createSandbox();
|
||||
// With useOpenWith disabled, a userChoice failure should skip the
|
||||
// IOpenWithLauncher branch entirely and fall straight through to the
|
||||
// modern settings dialog.
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
["browser.shell.setDefaultPDFHandler.useOpenWith", false],
|
||||
["browser.shell.setDefaultPDFHandler.attemptWaitTimeMs", 0],
|
||||
],
|
||||
});
|
||||
|
||||
try {
|
||||
sandbox
|
||||
.stub(ShellService, "setAsDefaultPDFHandlerUserChoice")
|
||||
.rejects(new Error("mock userChoice failure"));
|
||||
sandbox.stub(ShellService, "_isWindows11").returns(true);
|
||||
sandbox.stub(ShellService, "isDefaultHandlerFor").returns(true);
|
||||
|
||||
Services.fog.testResetFOG();
|
||||
await ShellService.setAsDefaultPDFHandler(false);
|
||||
|
||||
Assert.ok(
|
||||
launchOpenWithDefaultPickerForFileTypeStub.notCalled,
|
||||
"Did not invoke open-with picker when pref is disabled"
|
||||
);
|
||||
Assert.ok(
|
||||
launchModernSettingsDialogDefaultAppsStub.called,
|
||||
"Fell through to modern settings dialog"
|
||||
);
|
||||
|
||||
const event = await awaitAttemptEvent();
|
||||
Assert.equal(
|
||||
event.extra.method,
|
||||
"settings",
|
||||
"Event method skipped open_with and recorded settings"
|
||||
);
|
||||
Assert.equal(event.extra.success, "true", "Event success is true");
|
||||
Assert.equal(
|
||||
event.extra.result_is_default,
|
||||
"true",
|
||||
"Event result_is_default reflects isDefaultHandlerFor"
|
||||
);
|
||||
} finally {
|
||||
launchOpenWithDefaultPickerForFileTypeStub.reset();
|
||||
launchModernSettingsDialogDefaultAppsStub.reset();
|
||||
sandbox.restore();
|
||||
await SpecialPowers.popPrefEnv();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -16,7 +16,7 @@ add_task(async function () {
|
||||
await BrowserTestUtils.withNewTab(
|
||||
{
|
||||
gBrowser,
|
||||
url: "about:logo",
|
||||
url: getRootDirectory(gTestPath) + "large.png",
|
||||
},
|
||||
async () => {
|
||||
const dialogLoad = BrowserTestUtils.domWindowOpened(null, async win => {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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/. */
|
||||
|
||||
BIN
src/zen/tests/mochitests/shell/large.png
Normal file
BIN
src/zen/tests/mochitests/shell/large.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 21 KiB |
131
src/zen/tests/mochitests/shell/unit/test_desktopEntryStatus.js
Normal file
131
src/zen/tests/mochitests/shell/unit/test_desktopEntryStatus.js
Normal file
@@ -0,0 +1,131 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
ChromeUtils.defineESModuleGetters(this, {
|
||||
ShellService: "moz-src:///browser/components/shell/ShellService.sys.mjs",
|
||||
});
|
||||
|
||||
const BAREBONES_DESKTOP_ENTRY = `[Desktop Entry]
|
||||
Version=1.5
|
||||
Type=Application
|
||||
Name=test_desktopEntryStatus.js test case
|
||||
`;
|
||||
|
||||
let gHomeDir;
|
||||
let gSystemDir;
|
||||
|
||||
const filename = what => `test_desktopEntryStatus_file_${what}.desktop`;
|
||||
|
||||
// GLib caches results for efficiency. Unfortunately, it doesn't really provide
|
||||
// a way to invalidate that cache, aside from hoping that the file monitor
|
||||
// picks up on it. Resolve this by setting up all of the desktop entries at the
|
||||
// start, then doing checks, then exiting.
|
||||
//
|
||||
// (Some others are special-cased, namely absent and Hidden= checks.)
|
||||
const kDesktopEntries = [
|
||||
{
|
||||
label: "visible",
|
||||
content: BAREBONES_DESKTOP_ENTRY,
|
||||
expected: Ci.nsIGNOMEShellService.DESKTOP_ENTRY_VISIBLE,
|
||||
},
|
||||
{
|
||||
label: "nodisplay",
|
||||
content: BAREBONES_DESKTOP_ENTRY + "NoDisplay=true\n",
|
||||
expected: Ci.nsIGNOMEShellService.DESKTOP_ENTRY_INVISIBLE,
|
||||
},
|
||||
{
|
||||
label: "onlyshowin-matching",
|
||||
content: BAREBONES_DESKTOP_ENTRY + "OnlyShowIn=FirefoxOS\n",
|
||||
expected: Ci.nsIGNOMEShellService.DESKTOP_ENTRY_VISIBLE,
|
||||
},
|
||||
{
|
||||
label: "onlyshowin-notmatching",
|
||||
content: BAREBONES_DESKTOP_ENTRY + "OnlyShowIn=another\n",
|
||||
expected: Ci.nsIGNOMEShellService.DESKTOP_ENTRY_INVISIBLE,
|
||||
},
|
||||
{
|
||||
label: "notshowin-matching",
|
||||
content: BAREBONES_DESKTOP_ENTRY + "NotShowIn=FirefoxOS\n",
|
||||
expected: Ci.nsIGNOMEShellService.DESKTOP_ENTRY_INVISIBLE,
|
||||
},
|
||||
{
|
||||
label: "notshowin-notmatching",
|
||||
content: BAREBONES_DESKTOP_ENTRY + "NotShowIn=another\n",
|
||||
expected: Ci.nsIGNOMEShellService.DESKTOP_ENTRY_VISIBLE,
|
||||
},
|
||||
];
|
||||
|
||||
add_setup(async function setup() {
|
||||
let unique = await IOUtils.createUniqueDirectory(
|
||||
Services.dirsvc.get("TmpD", Ci.nsIFile).path,
|
||||
"desktopEntryStatusTest"
|
||||
);
|
||||
|
||||
let homeDir = PathUtils.join(unique, "data-home");
|
||||
Services.env.set("XDG_DATA_HOME", homeDir);
|
||||
gHomeDir = PathUtils.join(homeDir, "applications");
|
||||
await IOUtils.makeDirectory(gHomeDir, { createAncestors: true });
|
||||
|
||||
let systemDir = PathUtils.join(unique, "data-system");
|
||||
Services.env.set("XDG_DATA_DIRS", systemDir);
|
||||
gSystemDir = PathUtils.join(systemDir, "applications");
|
||||
await IOUtils.makeDirectory(gSystemDir, { createAncestors: true });
|
||||
|
||||
Services.env.set("XDG_CURRENT_DESKTOP", "FirefoxOS");
|
||||
|
||||
await IOUtils.writeUTF8(
|
||||
PathUtils.join(gHomeDir, filename("deleted")),
|
||||
BAREBONES_DESKTOP_ENTRY + "Hidden=true\n"
|
||||
);
|
||||
await IOUtils.writeUTF8(
|
||||
PathUtils.join(gSystemDir, filename("deleted")),
|
||||
BAREBONES_DESKTOP_ENTRY
|
||||
);
|
||||
|
||||
for (const desktopEntry of kDesktopEntries) {
|
||||
await IOUtils.writeUTF8(
|
||||
PathUtils.join(gHomeDir, filename(desktopEntry.label + "-home")),
|
||||
desktopEntry.content
|
||||
);
|
||||
await IOUtils.writeUTF8(
|
||||
PathUtils.join(gSystemDir, filename(desktopEntry.label + "-system")),
|
||||
desktopEntry.content
|
||||
);
|
||||
}
|
||||
|
||||
registerCleanupFunction(async () => {
|
||||
return IOUtils.remove(unique, { recursive: true });
|
||||
});
|
||||
});
|
||||
|
||||
add_task(function test_desktopEntryStatus() {
|
||||
Assert.equal(
|
||||
ShellService.getDesktopEntryStatus(filename("absent")),
|
||||
Ci.nsIGNOMEShellService.DESKTOP_ENTRY_ABSENT,
|
||||
"A desktop entry that doesn't exist should be absent."
|
||||
);
|
||||
Assert.equal(
|
||||
ShellService.getDesktopEntryStatus(filename("hidden")),
|
||||
Ci.nsIGNOMEShellService.DESKTOP_ENTRY_ABSENT,
|
||||
"A desktop entry shadowed by one with the Hidden= attribute should be absent."
|
||||
);
|
||||
|
||||
for (const desktopEntry of kDesktopEntries) {
|
||||
Assert.equal(
|
||||
ShellService.getDesktopEntryStatus(
|
||||
filename(desktopEntry.label + "-home")
|
||||
),
|
||||
desktopEntry.expected,
|
||||
"Desktop entry matches when at the local level: " + desktopEntry.label
|
||||
);
|
||||
Assert.equal(
|
||||
ShellService.getDesktopEntryStatus(
|
||||
filename(desktopEntry.label + "-system")
|
||||
),
|
||||
desktopEntry.expected,
|
||||
"Desktop entry matches when at the system level: " + desktopEntry.label
|
||||
);
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,109 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* https://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
ChromeUtils.defineESModuleGetters(this, {
|
||||
StartupOSIntegration:
|
||||
"moz-src:///browser/components/shell/StartupOSIntegration.sys.mjs",
|
||||
WindowsLaunchOnLogin: "resource://gre/modules/WindowsLaunchOnLogin.sys.mjs",
|
||||
sinon: "resource://testing-common/Sinon.sys.mjs",
|
||||
});
|
||||
|
||||
const PREF = "browser.startup.windowsLaunchOnLogin.defaultEnabled";
|
||||
|
||||
async function runWith({ isFirstRun, prefValue, approved }) {
|
||||
let sandbox = sinon.createSandbox();
|
||||
let approvedStub = sandbox
|
||||
.stub(WindowsLaunchOnLogin, "getLaunchOnLoginApproved")
|
||||
.resolves(approved);
|
||||
let createStub = sandbox
|
||||
.stub(WindowsLaunchOnLogin, "createLaunchOnLogin")
|
||||
.resolves();
|
||||
|
||||
if (prefValue === null) {
|
||||
Services.prefs.clearUserPref(PREF);
|
||||
} else {
|
||||
Services.prefs.setBoolPref(PREF, prefValue);
|
||||
}
|
||||
|
||||
try {
|
||||
await StartupOSIntegration.maybeCreateLaunchOnLoginOnFirstRun(isFirstRun);
|
||||
return { approvedStub, createStub };
|
||||
} finally {
|
||||
sandbox.restore();
|
||||
Services.prefs.clearUserPref(PREF);
|
||||
}
|
||||
}
|
||||
|
||||
add_task(async function test_creates_when_all_conditions_true() {
|
||||
let { createStub } = await runWith({
|
||||
isFirstRun: true,
|
||||
prefValue: true,
|
||||
approved: true,
|
||||
});
|
||||
Assert.ok(
|
||||
createStub.calledOnce,
|
||||
"createLaunchOnLogin should be called when isFirstRun, pref, and approval are all true"
|
||||
);
|
||||
});
|
||||
|
||||
add_task(async function test_skips_when_not_first_run() {
|
||||
let { createStub, approvedStub } = await runWith({
|
||||
isFirstRun: false,
|
||||
prefValue: true,
|
||||
approved: true,
|
||||
});
|
||||
Assert.ok(
|
||||
!createStub.called,
|
||||
"createLaunchOnLogin should not be called when isFirstRun is false"
|
||||
);
|
||||
Assert.ok(
|
||||
!approvedStub.called,
|
||||
"getLaunchOnLoginApproved should be short-circuited when isFirstRun is false"
|
||||
);
|
||||
});
|
||||
|
||||
add_task(async function test_skips_when_pref_disabled() {
|
||||
let { createStub, approvedStub } = await runWith({
|
||||
isFirstRun: true,
|
||||
prefValue: false,
|
||||
approved: true,
|
||||
});
|
||||
Assert.ok(
|
||||
!createStub.called,
|
||||
"createLaunchOnLogin should not be called when pref is false"
|
||||
);
|
||||
Assert.ok(
|
||||
!approvedStub.called,
|
||||
"getLaunchOnLoginApproved should be short-circuited when pref is false"
|
||||
);
|
||||
});
|
||||
|
||||
add_task(async function test_skips_when_windows_policy_denies() {
|
||||
let { createStub, approvedStub } = await runWith({
|
||||
isFirstRun: true,
|
||||
prefValue: true,
|
||||
approved: false,
|
||||
});
|
||||
Assert.ok(
|
||||
approvedStub.calledOnce,
|
||||
"getLaunchOnLoginApproved should be consulted when pref and isFirstRun are true"
|
||||
);
|
||||
Assert.ok(
|
||||
!createStub.called,
|
||||
"createLaunchOnLogin should not be called when Windows policy denies"
|
||||
);
|
||||
});
|
||||
|
||||
add_task(async function test_uses_pref_default_when_unset() {
|
||||
let { createStub } = await runWith({
|
||||
isFirstRun: true,
|
||||
prefValue: null,
|
||||
approved: true,
|
||||
});
|
||||
Assert.ok(
|
||||
createStub.calledOnce,
|
||||
"createLaunchOnLogin should be called when pref is at its built-in default of true"
|
||||
);
|
||||
});
|
||||
@@ -5,6 +5,11 @@ run-if = [
|
||||
firefox-appdir = "browser"
|
||||
tags = "os_integration"
|
||||
|
||||
["test_desktopEntryStatus.js"]
|
||||
run-if = [
|
||||
"os == 'linux'",
|
||||
]
|
||||
|
||||
["test_linuxDesktopEntry.js"]
|
||||
run-if = [
|
||||
"os == 'linux'",
|
||||
@@ -15,6 +20,11 @@ run-if = [
|
||||
"os == 'mac'",
|
||||
]
|
||||
|
||||
["test_maybeCreateLaunchOnLoginOnFirstRun.js"]
|
||||
run-if = [
|
||||
"os == 'win'"
|
||||
]
|
||||
|
||||
["test_secondaryTileJs.js"]
|
||||
run-if = [
|
||||
"os == 'win'"
|
||||
|
||||
@@ -63,7 +63,7 @@ async function do_test(test) {
|
||||
if (test.value) {
|
||||
info("Creating mock filepicker to select files");
|
||||
let MockFilePicker = SpecialPowers.MockFilePicker;
|
||||
MockFilePicker.init(window.browsingContext);
|
||||
MockFilePicker.init();
|
||||
MockFilePicker.returnValue = MockFilePicker.returnOK;
|
||||
MockFilePicker.displayDirectory = FileUtils.getDir("TmpD", []);
|
||||
MockFilePicker.setFiles([tempFile]);
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"version": {
|
||||
"product": "firefox",
|
||||
"version": "151.0.4",
|
||||
"candidate": "151.0.4",
|
||||
"candidate": "152.0",
|
||||
"candidateBuild": 1
|
||||
},
|
||||
"buildOptions": {
|
||||
|
||||
Reference in New Issue
Block a user