Update On Wed Jan 4 19:48:43 CET 2023

This commit is contained in:
github-action[bot] 2023-01-04 19:48:44 +01:00
parent f7d385a782
commit 0cc02130fe
2206 changed files with 33044 additions and 11707 deletions

33
Cargo.lock generated
View file

@ -2230,6 +2230,7 @@ dependencies = [
"uniffi-example-rondpoint",
"uniffi-example-sprites",
"uniffi-example-todolist",
"uniffi-fixture-callbacks",
"uniffi-fixture-external-types",
"url",
"viaduct",
@ -5769,8 +5770,8 @@ dependencies = [
[[package]]
name = "uniffi-example-arithmetic"
version = "0.18.0"
source = "git+https://github.com/mozilla/uniffi-rs.git?rev=bb2039f077a29dba0879372a67e764e6ace8e33f#bb2039f077a29dba0879372a67e764e6ace8e33f"
version = "0.21.0"
source = "git+https://github.com/mozilla/uniffi-rs.git?rev=846612a1d4fb5d11e246bf0682da4a499409424c#846612a1d4fb5d11e246bf0682da4a499409424c"
dependencies = [
"thiserror",
"uniffi",
@ -5793,8 +5794,8 @@ dependencies = [
[[package]]
name = "uniffi-example-geometry"
version = "0.18.0"
source = "git+https://github.com/mozilla/uniffi-rs.git?rev=bb2039f077a29dba0879372a67e764e6ace8e33f#bb2039f077a29dba0879372a67e764e6ace8e33f"
version = "0.21.0"
source = "git+https://github.com/mozilla/uniffi-rs.git?rev=846612a1d4fb5d11e246bf0682da4a499409424c#846612a1d4fb5d11e246bf0682da4a499409424c"
dependencies = [
"uniffi",
"uniffi_build",
@ -5803,8 +5804,8 @@ dependencies = [
[[package]]
name = "uniffi-example-rondpoint"
version = "0.18.0"
source = "git+https://github.com/mozilla/uniffi-rs.git?rev=bb2039f077a29dba0879372a67e764e6ace8e33f#bb2039f077a29dba0879372a67e764e6ace8e33f"
version = "0.21.0"
source = "git+https://github.com/mozilla/uniffi-rs.git?rev=846612a1d4fb5d11e246bf0682da4a499409424c#846612a1d4fb5d11e246bf0682da4a499409424c"
dependencies = [
"uniffi",
"uniffi_build",
@ -5813,8 +5814,8 @@ dependencies = [
[[package]]
name = "uniffi-example-sprites"
version = "0.18.0"
source = "git+https://github.com/mozilla/uniffi-rs.git?rev=bb2039f077a29dba0879372a67e764e6ace8e33f#bb2039f077a29dba0879372a67e764e6ace8e33f"
version = "0.21.0"
source = "git+https://github.com/mozilla/uniffi-rs.git?rev=846612a1d4fb5d11e246bf0682da4a499409424c#846612a1d4fb5d11e246bf0682da4a499409424c"
dependencies = [
"uniffi",
"uniffi_build",
@ -5823,10 +5824,20 @@ dependencies = [
[[package]]
name = "uniffi-example-todolist"
version = "0.18.0"
source = "git+https://github.com/mozilla/uniffi-rs.git?rev=bb2039f077a29dba0879372a67e764e6ace8e33f#bb2039f077a29dba0879372a67e764e6ace8e33f"
version = "0.21.0"
source = "git+https://github.com/mozilla/uniffi-rs.git?rev=846612a1d4fb5d11e246bf0682da4a499409424c#846612a1d4fb5d11e246bf0682da4a499409424c"
dependencies = [
"once_cell",
"thiserror",
"uniffi",
"uniffi_build",
"uniffi_macros",
]
[[package]]
name = "uniffi-fixture-callbacks"
version = "0.21.0"
dependencies = [
"lazy_static",
"thiserror",
"uniffi",
"uniffi_build",

View file

@ -61,7 +61,7 @@
unexpected: [[EVENT_SCROLLING_START, matchesAnchorJumpInTabDocument(1)]],
}, "Load background tab, don't dispatch scroll to anchor event");
tabBrowser().loadOneTab(URL, {
tabBrowser().addTab(URL, {
referrerURI: null,
charset: "",
postData: null,

View file

@ -52,11 +52,11 @@
}
}
function loadOneTab(aURI)
function addTab(aURI)
{
this.invoke = function loadOneTab_invoke()
this.invoke = function addTab_invoke()
{
tabBrowser().loadOneTab(aURI, {
tabBrowser().addTab(aURI, {
referrerURI: null,
charset: null,
postData: null,
@ -75,7 +75,7 @@
getAccessible(currentTabDocument()));
}
this.getID = function loadOneTab_getID()
this.getID = function addTab_getID()
{
return "load uri '" + aURI + "' in new tab";
}
@ -96,7 +96,7 @@
gQueue = new eventQueue();
gQueue.push(new loadURI("about:robots"));
gQueue.push(new loadOneTab("about:mozilla"));
gQueue.push(new addTab("about:mozilla"));
gQueue.onFinish = function()
{

View file

@ -53,6 +53,11 @@ LOCAL_INCLUDES += [
"/xpcom/build",
]
# The pthred_create() interposer needs to be linked as early as possible so
# that it will appear before libpthread when resolving symbols.
if CONFIG["OS_ARCH"] == "Linux" and CONFIG["MOZ_CRASHREPORTER"]:
USE_LIBS += ["pthread_create_interposer"]
if CONFIG["LIBFUZZER"]:
USE_LIBS += ["fuzzer"]
LOCAL_INCLUDES += [

View file

@ -517,9 +517,7 @@ var PlacesCommandHook = {
}
let parentGuid = await PlacesUIUtils.defaultParentGuid;
let parentId = await PlacesUtils.promiseItemId(parentGuid);
let defaultInsertionPoint = new PlacesInsertionPoint({
parentId,
parentGuid,
});
await PlacesUIUtils.showBookmarkDialog(
@ -1064,7 +1062,6 @@ var PlacesMenuDNDHandler = {
onDragOver: function PMDH_onDragOver(event) {
PlacesControllerDragHelper.currentDropTarget = event.target;
let ip = new PlacesInsertionPoint({
parentId: PlacesUtils.bookmarksMenuFolderId,
parentGuid: PlacesUtils.bookmarks.menuGuid,
});
if (ip && PlacesControllerDragHelper.canDrop(ip, event.dataTransfer)) {
@ -1082,7 +1079,6 @@ var PlacesMenuDNDHandler = {
onDrop: function PMDH_onDrop(event) {
// Put the item at the end of bookmark menu.
let ip = new PlacesInsertionPoint({
parentId: PlacesUtils.bookmarksMenuFolderId,
parentGuid: PlacesUtils.bookmarks.menuGuid,
});
PlacesControllerDragHelper.onDrop(ip, event.dataTransfer);

View file

@ -17,6 +17,11 @@ body {
text-rendering: optimizeLegibility;
min-height: 95px;
min-width: 95px;
/* z-indices that fight on the browser stack */
--browser-stack-z-index-devtools-splitter: 1;
--browser-stack-z-index-dialog-stack: 2;
--browser-stack-z-index-rdm-toolbar: 3;
}
:root:-moz-locale-dir(rtl) {
@ -1515,9 +1520,7 @@ toolbar[keyNav=true]:not([collapsed=true], [customizing=true]) toolbartabstop {
*/
.dialogStack {
/* Should outrank the z-index values of other UI elements, particularly the devtools
splitter element. */
z-index: 2;
z-index: var(--browser-stack-z-index-dialog-stack);
position: absolute;
inset: 0;
}

View file

@ -3263,7 +3263,7 @@ async function BrowserViewSourceOfDocument(args) {
// that fails. Either way, the view source module will manage the tab's
// location, so use "about:blank" here to avoid unnecessary redundant
// requests.
let tab = tabBrowser.loadOneTab("about:blank", {
let tab = tabBrowser.addTab("about:blank", {
relatedToCurrent: true,
inBackground: inNewWindow,
skipAnimation: inNewWindow,
@ -6200,7 +6200,7 @@ nsBrowserAccess.prototype = {
"browser.tabs.loadDivertedInBackground"
);
let tab = win.gBrowser.loadOneTab(aURI ? aURI.spec : "about:blank", {
let tab = win.gBrowser.addTab(aURI ? aURI.spec : "about:blank", {
triggeringPrincipal: aTriggeringPrincipal,
referrerInfo: aReferrerInfo,
userContextId: aUserContextId,

View file

@ -1529,13 +1529,13 @@ class nsContextMenu {
// We might also not have a tabBrowser reference (if this isn't in a
// a tabbrowser scope) or might have a fake/stub tabbrowser reference
// (in the sidebar). Deal with those cases:
if (!tabBrowser || !tabBrowser.loadOneTab || !window.toolbar.visible) {
if (!tabBrowser || !tabBrowser.addTab || !window.toolbar.visible) {
// This returns only non-popup browser windows by default.
let browserWindow = BrowserWindowTracker.getTopWindow();
tabBrowser = browserWindow.gBrowser;
}
let relatedToCurrent = gBrowser && gBrowser.selectedBrowser == browser;
let tab = tabBrowser.loadOneTab("about:blank", {
let tab = tabBrowser.addTab("about:blank", {
relatedToCurrent,
inBackground: inNewWindow,
skipAnimation: inNewWindow,
@ -1635,7 +1635,7 @@ class nsContextMenu {
referrerInfo,
triggeringPrincipal: systemPrincipal,
});
}, Cu.reportError);
}, console.error);
} else {
urlSecurityCheck(
this.mediaURL,
@ -2034,7 +2034,7 @@ class nsContextMenu {
isPrivate,
document.nodePrincipal /* system, because blob: */
);
}, Cu.reportError);
}, console.error);
} else if (this.onImage) {
urlSecurityCheck(this.mediaURL, this.principal);
internalSave(

View file

@ -1718,28 +1718,6 @@
return true;
},
loadOneTab(uri, params) {
// all callers of loadOneTab need to pass a valid triggeringPrincipal.
if (!params.triggeringPrincipal) {
throw new Error(
"Required argument triggeringPrincipal missing within loadOneTab"
);
}
params.inBackground ??= Services.prefs.getBoolPref(
"browser.tabs.loadInBackground"
);
params.ownerTab = params.inBackground ? null : this.selectedTab;
// Force boolean:
params.allowInheritPrincipal = !!params.allowInheritPrincipal;
let tab = this.addTab(uri, params);
if (!params.inBackground) {
this.selectedTab = tab;
}
return tab;
},
loadTabs(
aURIs,
{
@ -2560,6 +2538,7 @@
forceNotRemote,
forceAllowDataURI,
fromExternal,
inBackground = true,
index,
lazyTabTitle,
name,
@ -2598,6 +2577,9 @@
UserInteraction.start("browser.tabs.opening", "initting", window);
}
// If we're opening a foreground tab, set the owner by default.
ownerTab ??= inBackground ? null : this.selectedTab;
// Don't use document.l10n.setAttributes because the FTL file is loaded
// lazily and we won't be able to resolve the string.
document
@ -2945,6 +2927,9 @@
gSharedTabWarning.tabAdded(t);
if (!inBackground) {
this.selectedTab = t;
}
return t;
},

View file

@ -2,7 +2,7 @@
* http://creativecommons.org/publicdomain/zero/1.0/ */
add_task(async function checkIdentityOfAboutSupport() {
let tab = gBrowser.loadOneTab("about:support", {
let tab = gBrowser.addTab("about:support", {
referrerURI: null,
inBackground: false,
allowThirdPartyFixup: false,

View file

@ -7,7 +7,7 @@ var didFail = false;
// Override Alert to avoid blocking the test due to unknown protocol error
const kPromptServiceUUID = "{6cc9c9fe-bc0b-432b-a410-253ef8bcc699}";
const kPromptServiceContractID = "@mozilla.org/embedcomp/prompt-service;1";
const kPromptServiceContractID = "@mozilla.org/prompter;1";
// Save original prompt service factory
const kPromptServiceFactory = Cm.getClassObject(

View file

@ -9,7 +9,7 @@ function test() {
is(gBrowser.tabs.length, 1, "we start with one tab");
// create a tab
let tab = gBrowser.loadOneTab("about:blank", {
let tab = gBrowser.addTab("about:blank", {
triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
});
ok(!tab.hidden, "tab starts out not hidden");

View file

@ -35,7 +35,7 @@ function promiseNewChannelResponse(uri) {
"test-remote-troubleshooting-backchannel",
uri
);
let tab = gBrowser.loadOneTab(uri.spec, {
let tab = gBrowser.addTab(uri.spec, {
inBackground: false,
triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
});

View file

@ -211,6 +211,10 @@ var whitelist = [
// Files from upstream library
{ file: "resource://pdf.js/web/debugger.js" },
{ file: "resource://pdf.js/web/debugger.css" },
// A platform must be added here (see bug 1807983).
{ file: "resource://pdf.js/web/viewer-geckoview.css" },
{ file: "resource://pdf.js/web/viewer-geckoview.html" },
{ file: "resource://pdf.js/web/viewer-geckoview.js" },
// resource://app/modules/translation/TranslationContentHandler.jsm
{ file: "resource://app/modules/translation/BingTranslator.jsm" },

View file

@ -71,6 +71,18 @@ let whitelist = [
errorMessage: /Unknown property forced-color-adjust\. {2}Declaration dropped\./i,
isFromDevTools: false,
},
// PDF.js uses a property that is currently only supported in chrome.
{
sourceName: /web\/viewer-geckoview\.css$/i,
errorMessage: /Unknown property text-size-adjust\. {2}Declaration dropped\./i,
isFromDevTools: false,
},
// PDF.js uses a property that is currently only supported in chrome.
{
sourceName: /web\/viewer-geckoview\.css$/i,
errorMessage: /Unknown property forced-color-adjust\. {2}Declaration dropped\./i,
isFromDevTools: false,
},
{
sourceName: /overlay\.css$/i,
errorMessage: /Unknown pseudo-class.*moz-native-anonymous/i,
@ -145,6 +157,13 @@ let propNameWhitelist = [
// This variable is used from CSS embedded in JS in adjustableTitle.js
{ propName: "--icon-url", isFromDevTools: false },
// These are referenced from devtools files.
{
propName: "--browser-stack-z-index-devtools-splitter",
isFromDevTools: false,
},
{ propName: "--browser-stack-z-index-rdm-toolbar", isFromDevTools: false },
];
// Add suffix to stylesheets' URI so that we always load them here and

View file

@ -651,7 +651,7 @@ function openLinkIn(url, where, params) {
w.isBlankPageURL(url) &&
!AboutNewTab.willNotifyUser;
let tabUsedForLoad = w.gBrowser.loadOneTab(url, {
let tabUsedForLoad = w.gBrowser.addTab(url, {
referrerInfo: aReferrerInfo,
charset: aCharset,
postData: aPostData,

View file

@ -851,7 +851,7 @@ const listeners = {
try {
lazy[module].observe(subject, topic, data);
} catch (e) {
Cu.reportError(e);
console.error(e);
}
}
},
@ -1078,7 +1078,7 @@ BrowserGlue.prototype = {
subject.QueryInterface(Ci.nsISupportsString).data
);
} catch (ex) {
Cu.reportError(ex);
console.error(ex);
}
let win = lazy.BrowserWindowTracker.getTopWindow();
lazy.BrowserSearchTelemetry.recordSearch(
@ -1603,7 +1603,7 @@ BrowserGlue.prototype = {
secondsSinceLastOSRestart
);
} catch (ex) {
Cu.reportError(ex);
console.error(ex);
}
},
@ -2395,7 +2395,7 @@ BrowserGlue.prototype = {
try {
Services.logins;
} catch (ex) {
Cu.reportError(ex);
console.error(ex);
}
},
timeout: 3000,
@ -2435,7 +2435,7 @@ BrowserGlue.prototype = {
)
);
} catch (ex) {
Cu.reportError(ex);
console.error(ex);
}
let classification;
@ -2444,7 +2444,7 @@ BrowserGlue.prototype = {
shortcut = Services.appinfo.processStartupShortcut;
classification = shellService.classifyShortcut(shortcut);
} catch (ex) {
Cu.reportError(ex);
console.error(ex);
}
if (!classification) {
@ -2597,7 +2597,7 @@ BrowserGlue.prototype = {
).isAppInDock
);
} catch (ex) {
Cu.reportError(ex);
console.error(ex);
}
},
},
@ -2774,9 +2774,9 @@ BrowserGlue.prototype = {
try {
await lazy.BackgroundUpdate.scheduleFirefoxMessagingSystemTargetingSnapshotting();
} catch (e) {
Cu.reportError(
"There was an error scheduling Firefox Messaging System targeting snapshotting: " +
e
console.error(
"There was an error scheduling Firefox Messaging System targeting snapshotting: ",
e
);
}
await lazy.BackgroundUpdate.maybeScheduleBackgroundUpdateTask();
@ -2876,7 +2876,7 @@ BrowserGlue.prototype = {
try {
task.task();
} catch (ex) {
Cu.reportError(ex);
console.error(ex);
} finally {
ChromeUtils.addProfilerMarker(
"startupIdleTask",
@ -2946,7 +2946,7 @@ BrowserGlue.prototype = {
function CorroborateInit() {
if (Services.prefs.getBoolPref("corroborator.enabled", false)) {
lazy.Corroborate.init().catch(Cu.reportError);
lazy.Corroborate.init().catch(console.error);
}
},
@ -2989,7 +2989,7 @@ BrowserGlue.prototype = {
try {
await task();
} catch (ex) {
Cu.reportError(ex);
console.error(ex);
} finally {
ChromeUtils.addProfilerMarker(
"startupLateIdleTask",
@ -3328,7 +3328,7 @@ BrowserGlue.prototype = {
try {
await this._distributionCustomizer.applyBookmarks();
} catch (e) {
Cu.reportError(e);
console.error(e);
}
} else {
// An import operation is about to run.
@ -3353,17 +3353,17 @@ BrowserGlue.prototype = {
});
}
} catch (e) {
Cu.reportError("Bookmarks.html file could be corrupt. " + e);
console.error("Bookmarks.html file could be corrupt. ", e);
}
try {
// Now apply distribution customized bookmarks.
// This should always run after Places initialization.
await this._distributionCustomizer.applyBookmarks();
} catch (e) {
Cu.reportError(e);
console.error(e);
}
} else {
Cu.reportError(new Error("Unable to find bookmarks.html file."));
console.error(new Error("Unable to find bookmarks.html file."));
}
// Reset preferences, so we won't try to import again at next run
@ -3398,12 +3398,12 @@ BrowserGlue.prototype = {
// in some cases.
lazy.PlacesUIUtils.maybeToggleBookmarkToolbarVisibility();
} catch (ex) {
Cu.reportError(ex);
console.error(ex);
}
}
})()
.catch(ex => {
Cu.reportError(ex);
console.error(ex);
})
.then(() => {
// NB: deliberately after the catch so that we always do this, even if
@ -3898,7 +3898,7 @@ BrowserGlue.prototype = {
"geckoprofiler@mozilla.com"
);
} catch (error) {
Cu.reportError(
console.error(
"Could not access the AddonManager to upgrade the profile. This is most " +
"likely because the upgrader is being run from an xpcshell test where " +
"the AddonManager is not initialized."
@ -3913,9 +3913,9 @@ BrowserGlue.prototype = {
const wasAddonActive = addon.isActive;
addon
.uninstall()
.catch(Cu.reportError)
.catch(console.error)
.then(() => enableProfilerButton(wasAddonActive))
.catch(Cu.reportError);
.catch(console.error);
}, Cu.reportError);
}
@ -4239,7 +4239,7 @@ BrowserGlue.prototype = {
);
}
} catch (ex) {
Cu.reportError("Failed to clear XULStore PiP values: " + ex);
console.error("Failed to clear XULStore PiP values: ", ex);
}
}
@ -4297,7 +4297,7 @@ BrowserGlue.prototype = {
);
}
} catch (ex) {
Cu.reportError(`Error migrating ${id}'s ${attr} value: ` + ex);
console.error(`Error migrating ${id}'s ${attr} value: `, ex);
}
}
@ -4696,7 +4696,7 @@ BrowserGlue.prototype = {
clickCallback
);
} catch (ex) {
Cu.reportError("Error displaying tab(s) received by Sync: " + ex);
console.error("Error displaying tab(s) received by Sync: ", ex);
}
},
@ -4732,7 +4732,7 @@ BrowserGlue.prototype = {
clickCallback
);
} catch (ex) {
Cu.reportError("Error notifying of a verify login event: " + ex);
console.error("Error notifying of a verify login event: ", ex);
}
},
@ -4771,7 +4771,7 @@ BrowserGlue.prototype = {
clickCallback
);
} catch (ex) {
Cu.reportError("Error notifying of a new Sync device: " + ex);
console.error("Error notifying of a new Sync device: ", ex);
}
},
@ -5071,7 +5071,7 @@ var ContentBlockingCategoriesPrefs = {
Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN;
break;
default:
Cu.reportError(`Error: Unknown rule observed ${item}`);
console.error(`Error: Unknown rule observed ${item}`);
}
}
},
@ -5298,7 +5298,7 @@ ContentPermissionPrompt.prototype = {
permissionPrompt.prompt();
} catch (ex) {
Cu.reportError(ex);
console.error(ex);
request.cancel();
throw ex;
}
@ -5318,7 +5318,7 @@ ContentPermissionPrompt.prototype = {
// the request has likely been cancelled before being shown to the
// user. We shouldn't record this request.
if (ex.result != Cr.NS_ERROR_FAILURE) {
Cu.reportError(ex);
console.error(ex);
}
return;
}

View file

@ -302,7 +302,7 @@ CustomizeMode.prototype = {
if (!gTab) {
this.setTab(
this.browser.loadOneTab("about:blank", {
this.browser.addTab("about:blank", {
inBackground: false,
forceNotRemote: true,
skipAnimation: true,

View file

@ -353,14 +353,12 @@ function contentTriggerDblclickOn(selector, eventModifiers = {}, browser) {
ok(itemTarget, "Download item target exists");
let doubleClicked = ContentTaskUtils.waitForEvent(itemTarget, "dblclick");
EventUtils.synthesizeMouseAtCenter(
// NOTE: we are using sendMouseEvent instead of synthesizeMouseAtCenter
// here to prevent an unexpected timeout failure in devedition builds
// due to the ContentTaskUtils.waitForEvent promise never been resolved.
EventUtils.sendMouseEvent(
{ type: "dblclick", ...modifiers },
itemTarget,
Object.assign({ clickCount: 1 }, modifiers),
content
);
EventUtils.synthesizeMouseAtCenter(
itemTarget,
Object.assign({ clickCount: 2 }, modifiers),
content
);
info("Waiting for double-click content task");

View file

@ -151,6 +151,7 @@
},
"bookmarkId": {
"type": "string",
"optional": true,
"description": "The id of the bookmark where the context menu was clicked, if it was on a bookmark."
},
"modifiers": {

View file

@ -392,6 +392,11 @@ add_task(async function test_list_active_extensions_only() {
await openExtensionsPanel(aWin);
ok(
aWin.gUnifiedExtensions._button.open,
"Expected unified extension panel to be open"
);
const hiddenAddonItem = getUnifiedExtensionsItem(aWin, extensions[0].id);
is(hiddenAddonItem, null, "didn't expect an item for a hidden add-on");

View file

@ -150,10 +150,25 @@ const createExtensions = (
const ensureMaximizedWindow = async win => {
let resizeDone = Promise.resolve();
// Make sure we wait for window position to have settled
// to avoid unexpected failures.
let samePositionTimes = 0;
let lastScreenTop = win.screen.top;
let lastScreenLeft = win.screen.left;
win.moveTo(0, 0);
await TestUtils.waitForCondition(() => {
let isSamePosition =
lastScreenTop === win.screen.top && lastScreenLeft === win.screen.left;
if (!isSamePosition) {
lastScreenTop = win.screen.top;
lastScreenLeft = win.screen.left;
}
samePositionTimes = isSamePosition ? samePositionTimes + 1 : 0;
return samePositionTimes === 10;
}, "Wait for the chrome window position to settle");
const widthDiff = win.screen.availWidth - win.outerWidth;
const heightDiff = win.screen.availHeight - win.outerHeight;
const widthDiff = Math.max(win.screen.availWidth - win.outerWidth, 0);
const heightDiff = Math.max(win.screen.availHeight - win.outerHeight, 0);
if (widthDiff || heightDiff) {
resizeDone = BrowserTestUtils.waitForEvent(win, "resize", false);
@ -161,5 +176,20 @@ const ensureMaximizedWindow = async win => {
win.resizeBy(widthDiff, heightDiff);
}
return resizeDone;
await resizeDone;
// Make sure we wait for window size to have settled.
let lastOuterWidth = win.outerWidth;
let lastOuterHeight = win.outerHeight;
let sameSizeTimes = 0;
await TestUtils.waitForCondition(() => {
const isSameSize =
win.outerWidth === lastOuterWidth && win.outerHeight === lastOuterHeight;
if (!isSameSize) {
lastOuterWidth = win.outerWidth;
lastOuterHeight = win.outerHeight;
}
sameSizeTimes = isSameSize ? sameSizeTimes + 1 : 0;
return sameSizeTimes === 10;
}, "Wait for the chrome window size to settle");
};

View file

@ -21,7 +21,7 @@ add_task(async function() {
? "folders"
: "bookmarks"
]++;
if (event.parentId == PlacesUtils.toolbarFolderId) {
if (event.parentGuid == PlacesUtils.bookmarks.toolbarGuid) {
importedToBookmarksToolbar = true;
}
}

View file

@ -15,7 +15,7 @@ add_task(async function() {
// folders are created on the toolbar since the profile
// we're importing to has less than 3 bookmarks in the destination
// so a "From Safari" folder isn't created.
let expectedParents = [PlacesUtils.toolbarFolderId];
let expectedParentGuids = [PlacesUtils.bookmarks.toolbarGuid];
let itemCount = 0;
let gotFolder = false;
@ -28,10 +28,10 @@ add_task(async function() {
) {
gotFolder = true;
}
if (expectedParents.length) {
let index = expectedParents.indexOf(event.parentId);
if (expectedParentGuids.length) {
let index = expectedParentGuids.indexOf(event.parentGuid);
Assert.ok(index != -1, "Found expected parent");
expectedParents.splice(index, 1);
expectedParentGuids.splice(index, 1);
}
}
};
@ -56,7 +56,7 @@ add_task(async function() {
PlacesUtils.observers.removeListener(["bookmark-added"], listener);
// Check the bookmarks have been imported to all the expected parents.
Assert.ok(!expectedParents.length, "No more expected parents");
Assert.ok(!expectedParentGuids.length, "No more expected parents");
Assert.ok(gotFolder, "Should have seen the folder get imported");
Assert.equal(itemCount, 13, "Should import all 13 items.");
// Check that the telemetry matches:

View file

@ -433,12 +433,17 @@ const ProgressBar = ({
totalNumberOfScreens
}) => {
const [progress, setProgress] = react__WEBPACK_IMPORTED_MODULE_0___default().useState(previousStep / totalNumberOfScreens);
(0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => setProgress(step / totalNumberOfScreens), [step, totalNumberOfScreens]);
(0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
// We don't need to hook any dependencies because any time the step changes,
// the screen's entire DOM tree will be re-rendered.
setProgress(step / totalNumberOfScreens);
}, []); // eslint-disable-line react-hooks/exhaustive-deps
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
className: "indicator",
role: "presentation",
style: {
width: `${progress * 100}%`
"--progress-bar-progress": `${progress * 100}%`
}
});
};

View file

@ -313,7 +313,7 @@ html {
--translate: 30px;
--rotate: 20deg;
--scale: 0.4;
--progress-bar-transition: 0.6s width;
--progress-bar-transition: 0.6s translate;
}
.onboardingContainer:dir(rtl) {
--scale: -0.4 0.4;
@ -1141,6 +1141,7 @@ html {
font-weight: 400;
text-decoration: underline;
color: var(--in-content-link-color);
background: none;
}
.onboardingContainer .mobile-downloads .email-link:hover {
background: none;
@ -1285,13 +1286,18 @@ html {
transition: none;
}
.onboardingContainer .steps.progress-bar .indicator {
width: 100%;
height: 100%;
margin-inline: 0;
margin-inline: -1px;
background-color: var(--checkbox-checked-bgcolor);
border: 0;
border-radius: 0;
opacity: 1;
transition: var(--progress-bar-transition);
translate: calc(var(--progress-bar-progress, 0%) - 100%);
}
.onboardingContainer .steps.progress-bar .indicator:dir(rtl) {
translate: calc(var(--progress-bar-progress, 0%) * -1 + 100%);
}
.onboardingContainer .primary,
.onboardingContainer .secondary {

View file

@ -112,7 +112,7 @@ html {
--translate: 30px;
--rotate: 20deg;
--scale: 0.4;
--progress-bar-transition: 0.6s width;
--progress-bar-transition: 0.6s translate;
// Scale is used for noodles that can be flipped.
&:dir(rtl) {
@ -1122,6 +1122,7 @@ html {
font-weight: 400;
text-decoration: underline;
color: var(--in-content-link-color);
background: none;
&:hover {
background: none;
@ -1292,13 +1293,19 @@ html {
transition: none;
.indicator {
width: 100%;
height: 100%;
margin-inline: 0;
margin-inline: -1px;
background-color: var(--checkbox-checked-bgcolor);
border: 0;
border-radius: 0;
opacity: 1;
transition: var(--progress-bar-transition);
translate: calc(var(--progress-bar-progress, 0%) - 100%);
&:dir(rtl) {
translate: calc(var(--progress-bar-progress, 0%) * -1 + 100%);
}
}
}
}

View file

@ -289,15 +289,16 @@ export const ProgressBar = ({ step, previousStep, totalNumberOfScreens }) => {
const [progress, setProgress] = React.useState(
previousStep / totalNumberOfScreens
);
useEffect(() => setProgress(step / totalNumberOfScreens), [
step,
totalNumberOfScreens,
]);
useEffect(() => {
// We don't need to hook any dependencies because any time the step changes,
// the screen's entire DOM tree will be re-rendered.
setProgress(step / totalNumberOfScreens);
}, []); // eslint-disable-line react-hooks/exhaustive-deps
return (
<div
className="indicator"
role="presentation"
style={{ width: `${progress * 100}%` }}
style={{ "--progress-bar-progress": `${progress * 100}%` }}
/>
);
};

View file

@ -811,7 +811,9 @@ class PageAction {
if (
content.alt_anchor_id &&
lazy.CustomizableUI.getWidget(content.anchor_id).areaType === "menu-panel"
lazy.CustomizableUI.getWidget(content.anchor_id).areaType.includes(
"panel"
)
) {
anchor = this.window.document.getElementById(content.alt_anchor_id);
} else {
@ -819,7 +821,6 @@ class PageAction {
this.window.document.getElementById(content.anchor_id) ||
this.container;
}
browser.cfrpopupnotificationanchor = anchor;
await this._renderPopup(message, browser);

View file

@ -488,7 +488,7 @@ add_task(async function test_aboutwelcome_with_progress_bar() {
const progressBar = await ContentTaskUtils.waitForCondition(() =>
content.document.querySelector(".progress-bar")
);
const indicator1 = await ContentTaskUtils.waitForCondition(() =>
const indicator = await ContentTaskUtils.waitForCondition(() =>
content.document.querySelector(".indicator")
);
// Progress bar should have a gray background.
@ -498,24 +498,24 @@ add_task(async function test_aboutwelcome_with_progress_bar() {
"Correct progress bar background"
);
const indicatorStyles = content.window.getComputedStyle(indicator1);
const indicatorStyles = content.window.getComputedStyle(indicator);
for (let [key, val] of Object.entries({
// The filled "completed" element should have
// `background-color: var(--checkbox-checked-bgcolor);`
"background-color": "rgb(0, 97, 224)",
// Base progress bar step styles.
height: "6px",
margin: "0px",
"margin-inline": "-1px",
"padding-block": "0px",
})) {
is(indicatorStyles[key], val, `Correct indicator ${key} style`);
}
const indicatorWidth = indicator1.clientWidth;
const indicatorX = indicator.getBoundingClientRect().x;
content.document.querySelector("button.primary").click();
await ContentTaskUtils.waitForCondition(
() =>
content.document.querySelector(".indicator")?.clientWidth >
indicatorWidth,
content.document.querySelector(".indicator")?.getBoundingClientRect()
.x > indicatorX,
"Indicator should have grown"
);
});

View file

@ -296,7 +296,7 @@ describe("MultiStageAboutWelcome module", () => {
assert.ok(wrapper.find("div.indicator").exists());
assert.propertyVal(
wrapper.find("div.indicator").prop("style"),
"width",
"--progress-bar-progress",
"50%"
);
});

View file

@ -920,6 +920,61 @@ describe("CFRPageActions", () => {
});
});
describe("showPopup", () => {
let savedRec;
let pageAction;
let fakeAnchorId = "fake_anchor_id";
let sandboxShowPopup = sinon.createSandbox();
let fakePopUp = {
id: "fake_id",
template: "cfr_doorhanger",
content: {
skip_address_bar_notifier: true,
heading_text: "Fake Heading Text",
anchor_id: "fake_anchor_id",
},
};
beforeEach(() => {
const { id, content } = fakePopUp;
savedRec = {
id,
host: fakeHost,
content,
};
CFRPageActions.RecommendationMap.set(fakeBrowser, savedRec);
pageAction = new PageAction(window, dispatchStub);
sandboxShowPopup.stub(window.document, "getElementById");
sandboxShowPopup.stub(pageAction, "_renderPopup");
globals.set({
CustomizableUI: {
getWidget: sandboxShowPopup
.stub()
.withArgs(fakeAnchorId)
.returns({ areaType: "menu-panel" }),
},
});
});
afterEach(() => {
sandboxShowPopup.restore();
globals.restore();
});
it("Should use default anchor_id if an alternate hasn't been provided", async () => {
await pageAction.showPopup();
assert.calledWith(window.document.getElementById, fakeAnchorId);
});
it("Should use alt_anchor_if if one has been provided AND the anchor_id has been removed", async () => {
let fakeAltAnchorId = "fake_alt_anchor_id";
fakePopUp.content.alt_anchor_id = fakeAltAnchorId;
await pageAction.showPopup();
assert.calledWith(window.document.getElementById, fakeAltAnchorId);
});
});
describe("addRecommendation", () => {
it("should fail and not add a recommendation if the browser is part of a private window", async () => {
global.PrivateBrowsingUtils.isWindowPrivate.returns(true);

View file

@ -1006,8 +1006,8 @@ export var PlacesUIUtils = {
}
return (
lazy.PlacesUtils.getConcreteItemId(placesNode) ==
lazy.PlacesUtils.placesRootId
lazy.PlacesUtils.getConcreteItemGuid(placesNode) ==
lazy.PlacesUtils.bookmarks.rootGuid
);
},
@ -1837,8 +1837,9 @@ export var PlacesUIUtils = {
async db => {
let rows = await db.execute(
`SELECT COUNT(*) as n FROM moz_bookmarks b
WHERE b.parent = :parentId`,
{ parentId: lazy.PlacesUtils.toolbarFolderId }
JOIN moz_bookmarks p ON p.id = b.parent
WHERE p.guid = :guid`,
{ guid: lazy.PlacesUtils.bookmarks.toolbarGuid }
);
return rows[0].getResultByName("n");
}

View file

@ -158,10 +158,9 @@ var BookmarkPropertiesPanel = {
if ("defaultInsertionPoint" in dialogInfo) {
this._defaultInsertionPoint = dialogInfo.defaultInsertionPoint;
} else {
let guid = await PlacesUIUtils.defaultParentGuid;
let parentGuid = await PlacesUIUtils.defaultParentGuid;
this._defaultInsertionPoint = new PlacesInsertionPoint({
parentId: await PlacesUtils.promiseItemId(guid),
parentGuid: guid,
parentGuid,
});
}
@ -462,18 +461,13 @@ var BookmarkPropertiesPanel = {
*/
async _getInsertionPointDetails() {
return [
this._defaultInsertionPoint.itemId,
await this._defaultInsertionPoint.getIndex(),
this._defaultInsertionPoint.guid,
];
},
async _promiseNewItem() {
let [
containerId,
index,
parentGuid,
] = await this._getInsertionPointDetails();
let [index, parentGuid] = await this._getInsertionPointDetails();
let itemGuid;
let info = { parentGuid, index, title: this._title };
@ -510,6 +504,9 @@ var BookmarkPropertiesPanel = {
const itemId = gEditItemOverlay.delayedApplyEnabled
? undefined
: await PlacesUtils.promiseItemId(itemGuid);
const parentItemId = gEditItemOverlay.delayedApplyEnabled
? undefined
: await PlacesUtils.promiseItemId(parentGuid);
return Object.freeze({
itemId,
bookmarkGuid: itemGuid,
@ -520,7 +517,7 @@ var BookmarkPropertiesPanel = {
? Ci.nsINavHistoryResultNode.RESULT_TYPE_URI
: Ci.nsINavHistoryResultNode.RESULT_TYPE_FOLDER,
parent: {
itemId: containerId,
itemId: parentItemId,
bookmarkGuid: parentGuid,
type: Ci.nsINavHistoryResultNode.RESULT_TYPE_FOLDER,
},

View file

@ -229,7 +229,6 @@ class PlacesViewBase {
}
return new PlacesInsertionPoint({
parentId: PlacesUtils.getConcreteItemId(container),
parentGuid: PlacesUtils.getConcreteItemGuid(container),
index,
orientation,
@ -1555,7 +1554,6 @@ class PlacesToolbar extends PlacesViewBase {
) {
// Drop before this folder.
dropPoint.ip = new PlacesInsertionPoint({
parentId: PlacesUtils.getConcreteItemId(this._resultNode),
parentGuid: PlacesUtils.getConcreteItemGuid(this._resultNode),
index: eltIndex,
orientation: Ci.nsITreeView.DROP_BEFORE,
@ -1571,7 +1569,6 @@ class PlacesToolbar extends PlacesViewBase {
? elt._placesNode.title
: null;
dropPoint.ip = new PlacesInsertionPoint({
parentId: PlacesUtils.getConcreteItemId(elt._placesNode),
parentGuid: PlacesUtils.getConcreteItemGuid(elt._placesNode),
tagName,
});
@ -1583,7 +1580,6 @@ class PlacesToolbar extends PlacesViewBase {
eltIndex == this._rootElt.children.length - 1 ? -1 : eltIndex + 1;
dropPoint.ip = new PlacesInsertionPoint({
parentId: PlacesUtils.getConcreteItemId(this._resultNode),
parentGuid: PlacesUtils.getConcreteItemGuid(this._resultNode),
index: beforeIndex,
orientation: Ci.nsITreeView.DROP_BEFORE,
@ -1601,7 +1597,6 @@ class PlacesToolbar extends PlacesViewBase {
) {
// Drop before this bookmark.
dropPoint.ip = new PlacesInsertionPoint({
parentId: PlacesUtils.getConcreteItemId(this._resultNode),
parentGuid: PlacesUtils.getConcreteItemGuid(this._resultNode),
index: eltIndex,
orientation: Ci.nsITreeView.DROP_BEFORE,
@ -1612,7 +1607,6 @@ class PlacesToolbar extends PlacesViewBase {
let beforeIndex =
eltIndex == this._rootElt.children.length - 1 ? -1 : eltIndex + 1;
dropPoint.ip = new PlacesInsertionPoint({
parentId: PlacesUtils.getConcreteItemId(this._resultNode),
parentGuid: PlacesUtils.getConcreteItemGuid(this._resultNode),
index: beforeIndex,
orientation: Ci.nsITreeView.DROP_BEFORE,
@ -1624,7 +1618,6 @@ class PlacesToolbar extends PlacesViewBase {
// We are most likely dragging on the empty area of the
// toolbar, we should drop after the last node.
dropPoint.ip = new PlacesInsertionPoint({
parentId: PlacesUtils.getConcreteItemId(this._resultNode),
parentGuid: PlacesUtils.getConcreteItemGuid(this._resultNode),
orientation: Ci.nsITreeView.DROP_BEFORE,
});

View file

@ -17,9 +17,7 @@ ChromeUtils.defineESModuleGetters(this, {
* items.
*
* @param {object} options an object containing the following properties:
* @param {number} options.parentId
* The identifier of the parent container
* @param {*} options.parentGuid
* @param {string} options.parentGuid
* The unique identifier of the parent container
* @param {number} [options.index]
* The index within the container where to insert, defaults to appending
@ -34,14 +32,12 @@ ChromeUtils.defineESModuleGetters(this, {
* When defined index will be calculated based on this node
*/
function PlacesInsertionPoint({
parentId,
parentGuid,
index = PlacesUtils.bookmarks.DEFAULT_INDEX,
orientation = Ci.nsITreeView.DROP_ON,
tagName = null,
dropNearNode = null,
}) {
this.itemId = parentId;
this.guid = parentGuid;
this._index = index;
this.orientation = orientation;
@ -1450,7 +1446,9 @@ PlacesController.prototype = {
*/
var PlacesControllerDragHelper = {
/**
* DOM Element currently being dragged over
* For views using DOM nodes like toolbars, menus and panels, this is the DOM
* element currently being dragged over. For other views not handling DOM
* nodes, like trees, it is a Places result node instead.
*/
currentDropTarget: null,
@ -1559,18 +1557,39 @@ var PlacesControllerDragHelper = {
return false;
}
// The following loop disallows the dropping of a folder on itself or
// on any of its descendants.
// Disallow dropping of a folder on itself or any of its descendants.
// This check is done to show an appropriate drop indicator, a stricter
// check is done later by the bookmarks API.
if (
dragged.type == PlacesUtils.TYPE_X_MOZ_PLACE_CONTAINER ||
(dragged.uri && dragged.uri.startsWith("place:"))
) {
let parentId = ip.itemId;
while (parentId != PlacesUtils.placesRootId) {
if (dragged.concreteId == parentId || dragged.id == parentId) {
let dragOverPlacesNode = this.currentDropTarget;
if (!(dragOverPlacesNode instanceof Ci.nsINavHistoryResultNode)) {
// If it's a DOM node, it should have a _placesNode expando, or it
// may be a static element in a places container, like the [empty]
// menuitem.
dragOverPlacesNode =
dragOverPlacesNode._placesNode ??
dragOverPlacesNode.parentNode?._placesNode;
}
// If we couldn't get a target Places result node then we can't check
// whether the drag is allowed, just let it go through.
if (dragOverPlacesNode) {
let guid = dragged.concreteGuid ?? dragged.itemGuid;
// Dragging over itself.
if (PlacesUtils.getConcreteItemGuid(dragOverPlacesNode) == guid) {
return false;
}
parentId = PlacesUtils.bookmarks.getFolderIdForItem(parentId);
// Dragging over a descendant.
for (let ancestor of PlacesUtils.nodeAncestors(
dragOverPlacesNode
)) {
if (PlacesUtils.getConcreteItemGuid(ancestor) == guid) {
return false;
}
}
}
}

View file

@ -1042,7 +1042,6 @@ var gEditItemOverlay = {
// default to the bookmarks menu folder
if (!ip) {
ip = new PlacesInsertionPoint({
parentId: PlacesUtils.bookmarksMenuFolderId,
parentGuid: PlacesUtils.bookmarks.menuGuid,
});
}

View file

@ -1111,7 +1111,6 @@ var gEditItemOverlay = {
// default to the bookmarks menu folder
if (!ip) {
ip = new PlacesInsertionPoint({
parentId: PlacesUtils.bookmarksMenuFolderId,
parentGuid: PlacesUtils.bookmarks.menuGuid,
});
}

View file

@ -306,7 +306,6 @@ function closingPopupEndsDrag(popup) {
if (!elt._placesNode) {
// If we are dragging over a non places node drop at the end.
dropPoint.ip = new PlacesInsertionPoint({
parentId: PlacesUtils.getConcreteItemId(resultNode),
parentGuid: PlacesUtils.getConcreteItemGuid(resultNode),
});
// We can set folderElt if we are dropping over a static menu that
@ -337,7 +336,6 @@ function closingPopupEndsDrag(popup) {
if (eventY - eltY < eltHeight * 0.2) {
// If mouse is in the top part of the element, drop above folder.
dropPoint.ip = new PlacesInsertionPoint({
parentId: PlacesUtils.getConcreteItemId(resultNode),
parentGuid: PlacesUtils.getConcreteItemGuid(resultNode),
orientation: Ci.nsITreeView.DROP_BEFORE,
tagName,
@ -347,7 +345,6 @@ function closingPopupEndsDrag(popup) {
} else if (eventY - eltY < eltHeight * 0.8) {
// If mouse is in the middle of the element, drop inside folder.
dropPoint.ip = new PlacesInsertionPoint({
parentId: PlacesUtils.getConcreteItemId(elt._placesNode),
parentGuid: PlacesUtils.getConcreteItemGuid(elt._placesNode),
tagName,
});
@ -358,7 +355,6 @@ function closingPopupEndsDrag(popup) {
// This is a non-folder node or a readonly folder.
// If the mouse is above the middle, drop above this item.
dropPoint.ip = new PlacesInsertionPoint({
parentId: PlacesUtils.getConcreteItemId(resultNode),
parentGuid: PlacesUtils.getConcreteItemGuid(resultNode),
orientation: Ci.nsITreeView.DROP_BEFORE,
tagName,
@ -369,7 +365,6 @@ function closingPopupEndsDrag(popup) {
// Drop below the item.
dropPoint.ip = new PlacesInsertionPoint({
parentId: PlacesUtils.getConcreteItemId(resultNode),
parentGuid: PlacesUtils.getConcreteItemGuid(resultNode),
orientation: Ci.nsITreeView.DROP_AFTER,
tagName,

View file

@ -662,7 +662,6 @@
: null;
return new PlacesInsertionPoint({
parentId: PlacesUtils.getConcreteItemId(container),
parentGuid: PlacesUtils.getConcreteItemGuid(container),
index,
orientation,

View file

@ -740,10 +740,10 @@ var PlacesOrganizer = {
// don't update the panel if we are already editing this node unless we're
// in multi-edit mode
if (selectedNode) {
let concreteId = PlacesUtils.getConcreteItemId(selectedNode);
let concreteGuid = PlacesUtils.getConcreteItemGuid(selectedNode);
var nodeIsSame =
gEditItemOverlay.itemId == selectedNode.itemId ||
gEditItemOverlay.itemId == concreteId ||
gEditItemOverlay._paneInfo.itemGuid == concreteGuid ||
(selectedNode.itemId == -1 &&
gEditItemOverlay.uri &&
gEditItemOverlay.uri == selectedNode.uri);

View file

@ -1505,7 +1505,6 @@ PlacesTreeView.prototype = {
: null;
return new PlacesInsertionPoint({
parentId: PlacesUtils.getConcreteItemId(container),
parentGuid: PlacesUtils.getConcreteItemGuid(container),
index,
orientation,

View file

@ -116,8 +116,8 @@ add_task(async function test_query_on_toolbar() {
PO.selectLeftPaneBuiltIn("BookmarksToolbar");
Assert.notEqual(PO._places.selectedNode, null, "We have a valid selection");
Assert.equal(
PlacesUtils.getConcreteItemId(PO._places.selectedNode),
PlacesUtils.toolbarFolderId,
PlacesUtils.getConcreteItemGuid(PO._places.selectedNode),
PlacesUtils.bookmarks.toolbarGuid,
"We have correctly selected bookmarks toolbar node."
);
@ -217,8 +217,8 @@ add_task(async function test_search_contents() {
PO.selectLeftPaneBuiltIn("BookmarksToolbar");
Assert.notEqual(PO._places.selectedNode, null, "We have a valid selection");
Assert.equal(
PlacesUtils.getConcreteItemId(PO._places.selectedNode),
PlacesUtils.toolbarFolderId,
PlacesUtils.getConcreteItemGuid(PO._places.selectedNode),
PlacesUtils.bookmarks.toolbarGuid,
"We have correctly selected bookmarks toolbar node."
);

View file

@ -102,7 +102,6 @@ add_task(async function testActions() {
return Promise.resolve();
},
},
PlacesUtils: { bookmarksMenuFolderId: "id" },
},
openDialog() {},
openTrustedLinkIn() {},

View file

@ -39,7 +39,7 @@ let openUrl = url => {
ignoreFragment: "whenComparing",
});
} else {
window.gBrowser.loadOneTab(url, {
window.gBrowser.addTab(url, {
inBackground: false,
triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
});

View file

@ -337,7 +337,11 @@ export class UrlbarInput {
dueToSessionRestore = false,
dontShowSearchTerms = false
) {
if (!dontShowSearchTerms && this.window.gBrowser.userTypedValue == null) {
if (
!dontShowSearchTerms &&
(this.window.gBrowser.userTypedValue == null ||
this.window.gBrowser.userTypedValue == "")
) {
this.window.gBrowser.selectedBrowser.showingSearchTerms = false;
if (lazy.UrlbarPrefs.isPersistedSearchTermsEnabled()) {
let term = lazy.UrlbarSearchUtils.getSearchTermIfDefaultSerpUri(

View file

@ -103,6 +103,10 @@ support-files =
support-files = head-glean.js
[browser_glean_telemetry_abandonment_interaction.js]
support-files = head-glean.js
[browser_glean_telemetry_abandonment_interaction_persisted_search_terms_disabled.js]
support-files = head-glean.js
[browser_glean_telemetry_abandonment_interaction_persisted_search_terms_enabled.js]
support-files = head-glean.js
[browser_glean_telemetry_abandonment_n_chars_n_words.js]
support-files = head-glean.js
[browser_glean_telemetry_abandonment_preferences.js]
@ -115,6 +119,10 @@ support-files = head-glean.js
support-files = head-glean.js
[browser_glean_telemetry_engagement_interaction.js]
support-files = head-glean.js
[browser_glean_telemetry_engagement_interaction_persisted_search_terms_disabled.js]
support-files = head-glean.js
[browser_glean_telemetry_engagement_interaction_persisted_search_terms_enabled.js]
support-files = head-glean.js
[browser_glean_telemetry_engagement_n_chars_n_words.js]
support-files = head-glean.js
[browser_glean_telemetry_engagement_preferences.js]
@ -131,6 +139,10 @@ support-files = head-glean.js
support-files = head-glean.js
[browser_glean_telemetry_impression_interaction.js]
support-files = head-glean.js
[browser_glean_telemetry_impression_interaction_persisted_search_terms_disabled.js]
support-files = head-glean.js
[browser_glean_telemetry_impression_interaction_persisted_search_terms_enabled.js]
support-files = head-glean.js
[browser_glean_telemetry_impression_n_chars_n_words.js]
support-files = head-glean.js
[browser_glean_telemetry_impression_preferences.js]

View file

@ -135,3 +135,25 @@ add_task(async function user_overwrites_search_term() {
BrowserTestUtils.removeTab(tab1);
BrowserTestUtils.removeTab(tab2);
});
// If a user clears the URL bar, and goes to a different tab,
// the original tab should show the search term again.
add_task(async function user_overwrites_search_term() {
let { tab: tab1 } = await searchWithTab(SEARCH_STRING);
gURLBar.focus();
gURLBar.select();
EventUtils.sendKey("delete");
Assert.equal(gURLBar.value, "", "Empty string should be in url bar.");
// Open a new tab, switch back to the first and check
// the blank string is replaced with the search string.
let tab2 = await BrowserTestUtils.openNewForegroundTab(gBrowser);
await BrowserTestUtils.switchTab(gBrowser, tab1);
assertSearchStringIsInUrlbar(SEARCH_STRING);
BrowserTestUtils.removeTab(tab1);
BrowserTestUtils.removeTab(tab2);
});

View file

@ -119,204 +119,3 @@ add_task(async function interaction_returned_restarted_refined() {
});
}
});
add_task(async function interaction_persisted_search_terms() {
for (const showSearchTermsEnabled of [true, false]) {
await SpecialPowers.pushPrefEnv({
set: [
["browser.urlbar.showSearchTerms.featureGate", showSearchTermsEnabled],
["browser.urlbar.showSearchTerms.enabled", true],
["browser.search.widget.inNavBar", false],
],
});
await doTest(async browser => {
await openPopup("x");
await doEnter();
await openPopup("x");
await doBlur();
assertAbandonmentTelemetry([
{
interaction: showSearchTermsEnabled
? "persisted_search_terms"
: "typed",
},
]);
});
await SpecialPowers.popPrefEnv();
}
});
add_task(async function interaction_persisted_search_terms_restarted_refined() {
const testData = [
{
firstInput: "x",
// Just move the focus to the URL bar after engagement.
secondInput: null,
expectedForShowSearchTermsEnabled: "persisted_search_terms",
expectedForShowSearchTermsDisabled: "topsites",
},
{
firstInput: "x",
secondInput: "x",
expectedForShowSearchTermsEnabled: "persisted_search_terms",
expectedForShowSearchTermsDisabled: "typed",
},
{
firstInput: "x",
secondInput: "y",
expectedForShowSearchTermsEnabled: "persisted_search_terms_restarted",
expectedForShowSearchTermsDisabled: "typed",
},
{
firstInput: "x",
secondInput: "x y",
expectedForShowSearchTermsEnabled: "persisted_search_terms_refined",
expectedForShowSearchTermsDisabled: "typed",
},
{
firstInput: "x y",
secondInput: "x",
expectedForShowSearchTermsEnabled: "persisted_search_terms_refined",
expectedForShowSearchTermsDisabled: "typed",
},
];
for (const showSearchTermsEnabled of [true, false]) {
await SpecialPowers.pushPrefEnv({
set: [
["browser.urlbar.showSearchTerms.featureGate", showSearchTermsEnabled],
["browser.urlbar.showSearchTerms.enabled", true],
["browser.search.widget.inNavBar", false],
],
});
for (const {
firstInput,
secondInput,
expectedForShowSearchTermsEnabled,
expectedForShowSearchTermsDisabled,
} of testData) {
await doTest(async browser => {
await openPopup(firstInput);
await doEnter();
await UrlbarTestUtils.promisePopupOpen(window, () => {
EventUtils.synthesizeKey("l", { accelKey: true });
});
if (secondInput) {
for (let i = 0; i < secondInput.length; i++) {
EventUtils.synthesizeKey(secondInput.charAt(i));
}
}
await UrlbarTestUtils.promiseSearchComplete(window);
await doBlur();
assertAbandonmentTelemetry([
{
interaction: showSearchTermsEnabled
? expectedForShowSearchTermsEnabled
: expectedForShowSearchTermsDisabled,
},
]);
});
}
await SpecialPowers.popPrefEnv();
}
});
add_task(
async function interaction_persisted_search_terms_restarted_refined_via_abandonment() {
const testData = [
{
firstInput: "x",
// Just move the focus to the URL bar after blur.
secondInput: null,
expectedForShowSearchTermsEnabled: "persisted_search_terms",
expectedForShowSearchTermsDisabled: "returned",
},
{
firstInput: "x",
secondInput: "x",
expectedForShowSearchTermsEnabled: "persisted_search_terms",
expectedForShowSearchTermsDisabled: "returned",
},
{
firstInput: "x",
secondInput: "y",
expectedForShowSearchTermsEnabled: "persisted_search_terms_restarted",
expectedForShowSearchTermsDisabled: "restarted",
},
{
firstInput: "x",
secondInput: "x y",
expectedForShowSearchTermsEnabled: "persisted_search_terms_refined",
expectedForShowSearchTermsDisabled: "refined",
},
{
firstInput: "x y",
secondInput: "x",
expectedForShowSearchTermsEnabled: "persisted_search_terms_refined",
expectedForShowSearchTermsDisabled: "refined",
},
];
for (const showSearchTermsEnabled of [true, false]) {
await SpecialPowers.pushPrefEnv({
set: [
[
"browser.urlbar.showSearchTerms.featureGate",
showSearchTermsEnabled,
],
["browser.urlbar.showSearchTerms.enabled", true],
["browser.search.widget.inNavBar", false],
],
});
for (const {
firstInput,
secondInput,
expectedForShowSearchTermsEnabled,
expectedForShowSearchTermsDisabled,
} of testData) {
await doTest(async browser => {
await openPopup("any search");
await doEnter();
await openPopup(firstInput);
await doBlur();
await UrlbarTestUtils.promisePopupOpen(window, () => {
EventUtils.synthesizeKey("l", { accelKey: true });
});
if (secondInput) {
for (let i = 0; i < secondInput.length; i++) {
EventUtils.synthesizeKey(secondInput.charAt(i));
}
}
await UrlbarTestUtils.promiseSearchComplete(window);
await doBlur();
assertAbandonmentTelemetry([
{
interaction: showSearchTermsEnabled
? "persisted_search_terms_restarted"
: "typed",
},
{
interaction: showSearchTermsEnabled
? expectedForShowSearchTermsEnabled
: expectedForShowSearchTermsDisabled,
},
]);
});
}
await SpecialPowers.popPrefEnv();
}
}
);

View file

@ -0,0 +1,147 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Test abandonment telemetry with persisted search terms disabled.
// Allow more time for Mac machines so they don't time out in verify mode.
if (AppConstants.platform == "macosx") {
requestLongerTimeout(3);
}
/* import-globals-from head-glean.js */
Services.scriptloader.loadSubScript(
"chrome://mochitests/content/browser/browser/components/urlbar/tests/browser/head-glean.js",
this
);
add_setup(async function() {
await setup();
await SpecialPowers.pushPrefEnv({
set: [["browser.urlbar.showSearchTerms.featureGate", false]],
});
});
add_task(async function interaction_persisted_search_terms() {
await doTest(async browser => {
await openPopup("x");
await doEnter();
await openPopup("x");
await doBlur();
assertAbandonmentTelemetry([{ interaction: "typed" }]);
});
});
add_task(async function interaction_persisted_search_terms_restarted_refined() {
const testData = [
{
firstInput: "x",
// Just move the focus to the URL bar after engagement.
secondInput: null,
expected: "topsites",
},
{
firstInput: "x",
secondInput: "x",
expected: "typed",
},
{
firstInput: "x",
secondInput: "y",
expected: "typed",
},
{
firstInput: "x",
secondInput: "x y",
expected: "typed",
},
{
firstInput: "x y",
secondInput: "x",
expected: "typed",
},
];
for (const { firstInput, secondInput, expected } of testData) {
await doTest(async browser => {
await openPopup(firstInput);
await doEnter();
await UrlbarTestUtils.promisePopupOpen(window, () => {
EventUtils.synthesizeKey("l", { accelKey: true });
});
if (secondInput) {
for (let i = 0; i < secondInput.length; i++) {
EventUtils.synthesizeKey(secondInput.charAt(i));
}
}
await UrlbarTestUtils.promiseSearchComplete(window);
await doBlur();
assertAbandonmentTelemetry([{ interaction: expected }]);
});
}
});
add_task(
async function interaction_persisted_search_terms_restarted_refined_via_abandonment() {
const testData = [
{
firstInput: "x",
// Just move the focus to the URL bar after blur.
secondInput: null,
expected: "returned",
},
{
firstInput: "x",
secondInput: "x",
expected: "returned",
},
{
firstInput: "x",
secondInput: "y",
expected: "restarted",
},
{
firstInput: "x",
secondInput: "x y",
expected: "refined",
},
{
firstInput: "x y",
secondInput: "x",
expected: "refined",
},
];
for (const { firstInput, secondInput, expected } of testData) {
await doTest(async browser => {
await openPopup("any search");
await doEnter();
await openPopup(firstInput);
await doBlur();
await UrlbarTestUtils.promisePopupOpen(window, () => {
EventUtils.synthesizeKey("l", { accelKey: true });
});
if (secondInput) {
for (let i = 0; i < secondInput.length; i++) {
EventUtils.synthesizeKey(secondInput.charAt(i));
}
}
await UrlbarTestUtils.promiseSearchComplete(window);
await doBlur();
assertAbandonmentTelemetry([
{ interaction: "typed" },
{ interaction: expected },
]);
});
}
}
);

View file

@ -0,0 +1,151 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Test abandonment telemetry with persisted search terms enabled.
// Allow more time for Mac machines so they don't time out in verify mode.
if (AppConstants.platform == "macosx") {
requestLongerTimeout(3);
}
/* import-globals-from head-glean.js */
Services.scriptloader.loadSubScript(
"chrome://mochitests/content/browser/browser/components/urlbar/tests/browser/head-glean.js",
this
);
add_setup(async function() {
await setup();
await SpecialPowers.pushPrefEnv({
set: [
["browser.urlbar.showSearchTerms.featureGate", true],
["browser.urlbar.showSearchTerms.enabled", true],
["browser.search.widget.inNavBar", false],
],
});
});
add_task(async function interaction_persisted_search_terms() {
await doTest(async browser => {
await openPopup("x");
await doEnter();
await openPopup("x");
await doBlur();
assertAbandonmentTelemetry([{ interaction: "persisted_search_terms" }]);
});
});
add_task(async function interaction_persisted_search_terms_restarted_refined() {
const testData = [
{
firstInput: "x",
// Just move the focus to the URL bar after engagement.
secondInput: null,
expected: "persisted_search_terms",
},
{
firstInput: "x",
secondInput: "x",
expected: "persisted_search_terms",
},
{
firstInput: "x",
secondInput: "y",
expected: "persisted_search_terms_restarted",
},
{
firstInput: "x",
secondInput: "x y",
expected: "persisted_search_terms_refined",
},
{
firstInput: "x y",
secondInput: "x",
expected: "persisted_search_terms_refined",
},
];
for (const { firstInput, secondInput, expected } of testData) {
await doTest(async browser => {
await openPopup(firstInput);
await doEnter();
await UrlbarTestUtils.promisePopupOpen(window, () => {
EventUtils.synthesizeKey("l", { accelKey: true });
});
if (secondInput) {
for (let i = 0; i < secondInput.length; i++) {
EventUtils.synthesizeKey(secondInput.charAt(i));
}
}
await UrlbarTestUtils.promiseSearchComplete(window);
await doBlur();
assertAbandonmentTelemetry([{ interaction: expected }]);
});
}
});
add_task(
async function interaction_persisted_search_terms_restarted_refined_via_abandonment() {
const testData = [
{
firstInput: "x",
// Just move the focus to the URL bar after blur.
secondInput: null,
expected: "persisted_search_terms",
},
{
firstInput: "x",
secondInput: "x",
expected: "persisted_search_terms",
},
{
firstInput: "x",
secondInput: "y",
expected: "persisted_search_terms_restarted",
},
{
firstInput: "x",
secondInput: "x y",
expected: "persisted_search_terms_refined",
},
{
firstInput: "x y",
secondInput: "x",
expected: "persisted_search_terms_refined",
},
];
for (const { firstInput, secondInput, expected } of testData) {
await doTest(async browser => {
await openPopup("any search");
await doEnter();
await openPopup(firstInput);
await doBlur();
await UrlbarTestUtils.promisePopupOpen(window, () => {
EventUtils.synthesizeKey("l", { accelKey: true });
});
if (secondInput) {
for (let i = 0; i < secondInput.length; i++) {
EventUtils.synthesizeKey(secondInput.charAt(i));
}
}
await UrlbarTestUtils.promiseSearchComplete(window);
await doBlur();
assertAbandonmentTelemetry([
{ interaction: "persisted_search_terms_restarted" },
{ interaction: expected },
]);
});
}
}
);

View file

@ -6,6 +6,11 @@
// Test for the following data of engagement telemetry.
// - interaction
// Allow more time for Mac machines so they don't time out in verify mode.
if (AppConstants.platform == "macosx") {
requestLongerTimeout(3);
}
/* import-globals-from head-glean.js */
Services.scriptloader.loadSubScript(
"chrome://mochitests/content/browser/browser/components/urlbar/tests/browser/head-glean.js",
@ -145,202 +150,3 @@ add_task(async function interaction_returned_restarted_refined() {
});
}
});
add_task(async function interaction_persisted_search_terms() {
for (const showSearchTermsEnabled of [true, false]) {
await SpecialPowers.pushPrefEnv({
set: [
["browser.urlbar.showSearchTerms.featureGate", showSearchTermsEnabled],
["browser.urlbar.showSearchTerms.enabled", true],
["browser.search.widget.inNavBar", false],
],
});
await doTest(async browser => {
await openPopup("x");
await doEnter();
await openPopup("x");
await doEnter();
assertEngagementTelemetry([
{ interaction: "typed" },
{
interaction: showSearchTermsEnabled
? "persisted_search_terms"
: "typed",
},
]);
});
await SpecialPowers.popPrefEnv();
}
});
add_task(async function interaction_persisted_search_terms_restarted_refined() {
const testData = [
{
firstInput: "x",
// Just move the focus to the URL bar after engagement.
secondInput: null,
expectedForShowSearchTermsEnabled: "persisted_search_terms",
expectedForShowSearchTermsDisabled: "topsites",
},
{
firstInput: "x",
secondInput: "x",
expectedForShowSearchTermsEnabled: "persisted_search_terms",
expectedForShowSearchTermsDisabled: "typed",
},
{
firstInput: "x",
secondInput: "y",
expectedForShowSearchTermsEnabled: "persisted_search_terms_restarted",
expectedForShowSearchTermsDisabled: "typed",
},
{
firstInput: "x",
secondInput: "x y",
expectedForShowSearchTermsEnabled: "persisted_search_terms_refined",
expectedForShowSearchTermsDisabled: "typed",
},
{
firstInput: "x y",
secondInput: "x",
expectedForShowSearchTermsEnabled: "persisted_search_terms_refined",
expectedForShowSearchTermsDisabled: "typed",
},
];
for (const showSearchTermsEnabled of [true, false]) {
await SpecialPowers.pushPrefEnv({
set: [
["browser.urlbar.showSearchTerms.featureGate", showSearchTermsEnabled],
["browser.urlbar.showSearchTerms.enabled", true],
["browser.search.widget.inNavBar", false],
],
});
for (const {
firstInput,
secondInput,
expectedForShowSearchTermsEnabled,
expectedForShowSearchTermsDisabled,
} of testData) {
await doTest(async browser => {
await openPopup(firstInput);
await doEnter();
await UrlbarTestUtils.promisePopupOpen(window, () => {
EventUtils.synthesizeKey("l", { accelKey: true });
});
if (secondInput) {
for (let i = 0; i < secondInput.length; i++) {
EventUtils.synthesizeKey(secondInput.charAt(i));
}
}
await UrlbarTestUtils.promiseSearchComplete(window);
await doEnter();
assertEngagementTelemetry([
{ interaction: "typed" },
{
interaction: showSearchTermsEnabled
? expectedForShowSearchTermsEnabled
: expectedForShowSearchTermsDisabled,
},
]);
});
}
await SpecialPowers.popPrefEnv();
}
});
add_task(
async function interaction_persisted_search_terms_restarted_refined_via_abandonment() {
const testData = [
{
firstInput: "x",
// Just move the focus to the URL bar after blur.
secondInput: null,
expectedForShowSearchTermsEnabled: "persisted_search_terms",
expectedForShowSearchTermsDisabled: "returned",
},
{
firstInput: "x",
secondInput: "x",
expectedForShowSearchTermsEnabled: "persisted_search_terms",
expectedForShowSearchTermsDisabled: "returned",
},
{
firstInput: "x",
secondInput: "y",
expectedForShowSearchTermsEnabled: "persisted_search_terms_restarted",
expectedForShowSearchTermsDisabled: "restarted",
},
{
firstInput: "x",
secondInput: "x y",
expectedForShowSearchTermsEnabled: "persisted_search_terms_refined",
expectedForShowSearchTermsDisabled: "refined",
},
{
firstInput: "x y",
secondInput: "x",
expectedForShowSearchTermsEnabled: "persisted_search_terms_refined",
expectedForShowSearchTermsDisabled: "refined",
},
];
for (const showSearchTermsEnabled of [true, false]) {
await SpecialPowers.pushPrefEnv({
set: [
[
"browser.urlbar.showSearchTerms.featureGate",
showSearchTermsEnabled,
],
["browser.urlbar.showSearchTerms.enabled", true],
["browser.search.widget.inNavBar", false],
],
});
for (const {
firstInput,
secondInput,
expectedForShowSearchTermsEnabled,
expectedForShowSearchTermsDisabled,
} of testData) {
await doTest(async browser => {
await openPopup("any search");
await doEnter();
await openPopup(firstInput);
await doBlur();
await UrlbarTestUtils.promisePopupOpen(window, () => {
EventUtils.synthesizeKey("l", { accelKey: true });
});
if (secondInput) {
for (let i = 0; i < secondInput.length; i++) {
EventUtils.synthesizeKey(secondInput.charAt(i));
}
}
await UrlbarTestUtils.promiseSearchComplete(window);
await doEnter();
assertEngagementTelemetry([
{ interaction: "typed" },
{
interaction: showSearchTermsEnabled
? expectedForShowSearchTermsEnabled
: expectedForShowSearchTermsDisabled,
},
]);
});
}
await SpecialPowers.popPrefEnv();
}
}
);

View file

@ -0,0 +1,153 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Test engagement telemetry with persisted search terms disabled.
// Allow more time for Mac machines so they don't time out in verify mode.
if (AppConstants.platform == "macosx") {
requestLongerTimeout(3);
}
/* import-globals-from head-glean.js */
Services.scriptloader.loadSubScript(
"chrome://mochitests/content/browser/browser/components/urlbar/tests/browser/head-glean.js",
this
);
add_setup(async function() {
await setup();
await SpecialPowers.pushPrefEnv({
set: [["browser.urlbar.showSearchTerms.featureGate", false]],
});
});
add_task(async function interaction_persisted_search_terms() {
await doTest(async browser => {
await openPopup("x");
await doEnter();
await openPopup("x");
await doEnter();
assertEngagementTelemetry([
{ interaction: "typed" },
{ interaction: "typed" },
]);
});
});
add_task(async function interaction_persisted_search_terms_restarted_refined() {
const testData = [
{
firstInput: "x",
// Just move the focus to the URL bar after engagement.
secondInput: null,
expected: "topsites",
},
{
firstInput: "x",
secondInput: "x",
expected: "typed",
},
{
firstInput: "x",
secondInput: "y",
expected: "typed",
},
{
firstInput: "x",
secondInput: "x y",
expected: "typed",
},
{
firstInput: "x y",
secondInput: "x",
expected: "typed",
},
];
for (const { firstInput, secondInput, expected } of testData) {
await doTest(async browser => {
await openPopup(firstInput);
await doEnter();
await UrlbarTestUtils.promisePopupOpen(window, () => {
EventUtils.synthesizeKey("l", { accelKey: true });
});
if (secondInput) {
for (let i = 0; i < secondInput.length; i++) {
EventUtils.synthesizeKey(secondInput.charAt(i));
}
}
await UrlbarTestUtils.promiseSearchComplete(window);
await doEnter();
assertEngagementTelemetry([
{ interaction: "typed" },
{ interaction: expected },
]);
});
}
});
add_task(
async function interaction_persisted_search_terms_restarted_refined_via_abandonment() {
const testData = [
{
firstInput: "x",
// Just move the focus to the URL bar after blur.
secondInput: null,
expected: "returned",
},
{
firstInput: "x",
secondInput: "x",
expected: "returned",
},
{
firstInput: "x",
secondInput: "y",
expected: "restarted",
},
{
firstInput: "x",
secondInput: "x y",
expected: "refined",
},
{
firstInput: "x y",
secondInput: "x",
expected: "refined",
},
];
for (const { firstInput, secondInput, expected } of testData) {
await doTest(async browser => {
await openPopup("any search");
await doEnter();
await openPopup(firstInput);
await doBlur();
await UrlbarTestUtils.promisePopupOpen(window, () => {
EventUtils.synthesizeKey("l", { accelKey: true });
});
if (secondInput) {
for (let i = 0; i < secondInput.length; i++) {
EventUtils.synthesizeKey(secondInput.charAt(i));
}
}
await UrlbarTestUtils.promiseSearchComplete(window);
await doEnter();
assertEngagementTelemetry([
{ interaction: "typed" },
{ interaction: expected },
]);
});
}
}
);

View file

@ -0,0 +1,157 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Test engagement telemetry with persisted search terms enabled.
// Allow more time for Mac machines so they don't time out in verify mode.
if (AppConstants.platform == "macosx") {
requestLongerTimeout(3);
}
/* import-globals-from head-glean.js */
Services.scriptloader.loadSubScript(
"chrome://mochitests/content/browser/browser/components/urlbar/tests/browser/head-glean.js",
this
);
add_setup(async function() {
await setup();
await SpecialPowers.pushPrefEnv({
set: [
["browser.urlbar.showSearchTerms.featureGate", true],
["browser.urlbar.showSearchTerms.enabled", true],
["browser.search.widget.inNavBar", false],
],
});
});
add_task(async function interaction_persisted_search_terms() {
await doTest(async browser => {
await openPopup("x");
await doEnter();
await openPopup("x");
await doEnter();
assertEngagementTelemetry([
{ interaction: "typed" },
{ interaction: "persisted_search_terms" },
]);
});
});
add_task(async function interaction_persisted_search_terms_restarted_refined() {
const testData = [
{
firstInput: "x",
// Just move the focus to the URL bar after engagement.
secondInput: null,
expected: "persisted_search_terms",
},
{
firstInput: "x",
secondInput: "x",
expected: "persisted_search_terms",
},
{
firstInput: "x",
secondInput: "y",
expected: "persisted_search_terms_restarted",
},
{
firstInput: "x",
secondInput: "x y",
expected: "persisted_search_terms_refined",
},
{
firstInput: "x y",
secondInput: "x",
expected: "persisted_search_terms_refined",
},
];
for (const { firstInput, secondInput, expected } of testData) {
await doTest(async browser => {
await openPopup(firstInput);
await doEnter();
await UrlbarTestUtils.promisePopupOpen(window, () => {
EventUtils.synthesizeKey("l", { accelKey: true });
});
if (secondInput) {
for (let i = 0; i < secondInput.length; i++) {
EventUtils.synthesizeKey(secondInput.charAt(i));
}
}
await UrlbarTestUtils.promiseSearchComplete(window);
await doEnter();
assertEngagementTelemetry([
{ interaction: "typed" },
{ interaction: expected },
]);
});
}
});
add_task(
async function interaction_persisted_search_terms_restarted_refined_via_abandonment() {
const testData = [
{
firstInput: "x",
// Just move the focus to the URL bar after blur.
secondInput: null,
expected: "persisted_search_terms",
},
{
firstInput: "x",
secondInput: "x",
expected: "persisted_search_terms",
},
{
firstInput: "x",
secondInput: "y",
expected: "persisted_search_terms_restarted",
},
{
firstInput: "x",
secondInput: "x y",
expected: "persisted_search_terms_refined",
},
{
firstInput: "x y",
secondInput: "x",
expected: "persisted_search_terms_refined",
},
];
for (const { firstInput, secondInput, expected } of testData) {
await doTest(async browser => {
await openPopup("any search");
await doEnter();
await openPopup(firstInput);
await doBlur();
await UrlbarTestUtils.promisePopupOpen(window, () => {
EventUtils.synthesizeKey("l", { accelKey: true });
});
if (secondInput) {
for (let i = 0; i < secondInput.length; i++) {
EventUtils.synthesizeKey(secondInput.charAt(i));
}
}
await UrlbarTestUtils.promiseSearchComplete(window);
await doEnter();
assertEngagementTelemetry([
{ interaction: "typed" },
{ interaction: expected },
]);
});
}
}
);

View file

@ -128,207 +128,3 @@ add_task(async function interaction_returned_restarted_refined() {
});
}
});
add_task(async function interaction_persisted_search_terms() {
for (const showSearchTermsEnabled of [true, false]) {
await SpecialPowers.pushPrefEnv({
set: [
["browser.urlbar.showSearchTerms.featureGate", showSearchTermsEnabled],
["browser.urlbar.showSearchTerms.enabled", true],
["browser.search.widget.inNavBar", false],
],
});
await doTest(async browser => {
await openPopup("x");
await waitForPauseImpression();
await doEnter();
await openPopup("x");
await waitForPauseImpression();
assertImpressionTelemetry([
{ reason: "pause" },
{
interaction: showSearchTermsEnabled
? "persisted_search_terms"
: "typed",
},
]);
});
await SpecialPowers.popPrefEnv();
}
});
add_task(async function interaction_persisted_search_terms_restarted_refined() {
const testData = [
{
firstInput: "x",
// Just move the focus to the URL bar after engagement.
secondInput: null,
expectedForShowSearchTermsEnabled: "persisted_search_terms",
expectedForShowSearchTermsDisabled: "topsites",
},
{
firstInput: "x",
secondInput: "x",
expectedForShowSearchTermsEnabled: "persisted_search_terms",
expectedForShowSearchTermsDisabled: "typed",
},
{
firstInput: "x",
secondInput: "y",
expectedForShowSearchTermsEnabled: "persisted_search_terms_restarted",
expectedForShowSearchTermsDisabled: "typed",
},
{
firstInput: "x",
secondInput: "x y",
expectedForShowSearchTermsEnabled: "persisted_search_terms_refined",
expectedForShowSearchTermsDisabled: "typed",
},
{
firstInput: "x y",
secondInput: "x",
expectedForShowSearchTermsEnabled: "persisted_search_terms_refined",
expectedForShowSearchTermsDisabled: "typed",
},
];
for (const showSearchTermsEnabled of [true, false]) {
await SpecialPowers.pushPrefEnv({
set: [
["browser.urlbar.showSearchTerms.featureGate", showSearchTermsEnabled],
["browser.urlbar.showSearchTerms.enabled", true],
["browser.search.widget.inNavBar", false],
],
});
for (const {
firstInput,
secondInput,
expectedForShowSearchTermsEnabled,
expectedForShowSearchTermsDisabled,
} of testData) {
await doTest(async browser => {
await openPopup(firstInput);
await waitForPauseImpression();
await doEnter();
await UrlbarTestUtils.promisePopupOpen(window, () => {
EventUtils.synthesizeKey("l", { accelKey: true });
});
if (secondInput) {
for (let i = 0; i < secondInput.length; i++) {
EventUtils.synthesizeKey(secondInput.charAt(i));
}
}
await UrlbarTestUtils.promiseSearchComplete(window);
await waitForPauseImpression();
assertImpressionTelemetry([
{ reason: "pause" },
{
interaction: showSearchTermsEnabled
? expectedForShowSearchTermsEnabled
: expectedForShowSearchTermsDisabled,
},
]);
});
}
await SpecialPowers.popPrefEnv();
}
});
add_task(
async function interaction_persisted_search_terms_restarted_refined_via_abandonment() {
const testData = [
{
firstInput: "x",
// Just move the focus to the URL bar after blur.
secondInput: null,
expectedForShowSearchTermsEnabled: "persisted_search_terms",
expectedForShowSearchTermsDisabled: "returned",
},
{
firstInput: "x",
secondInput: "x",
expectedForShowSearchTermsEnabled: "persisted_search_terms",
expectedForShowSearchTermsDisabled: "returned",
},
{
firstInput: "x",
secondInput: "y",
expectedForShowSearchTermsEnabled: "persisted_search_terms_restarted",
expectedForShowSearchTermsDisabled: "restarted",
},
{
firstInput: "x",
secondInput: "x y",
expectedForShowSearchTermsEnabled: "persisted_search_terms_refined",
expectedForShowSearchTermsDisabled: "refined",
},
{
firstInput: "x y",
secondInput: "x",
expectedForShowSearchTermsEnabled: "persisted_search_terms_refined",
expectedForShowSearchTermsDisabled: "refined",
},
];
for (const showSearchTermsEnabled of [true, false]) {
await SpecialPowers.pushPrefEnv({
set: [
[
"browser.urlbar.showSearchTerms.featureGate",
showSearchTermsEnabled,
],
["browser.urlbar.showSearchTerms.enabled", true],
["browser.search.widget.inNavBar", false],
],
});
for (const {
firstInput,
secondInput,
expectedForShowSearchTermsEnabled,
expectedForShowSearchTermsDisabled,
} of testData) {
await doTest(async browser => {
await openPopup("any search");
await waitForPauseImpression();
await doEnter();
await openPopup(firstInput);
await waitForPauseImpression();
await doBlur();
await UrlbarTestUtils.promisePopupOpen(window, () => {
EventUtils.synthesizeKey("l", { accelKey: true });
});
if (secondInput) {
for (let i = 0; i < secondInput.length; i++) {
EventUtils.synthesizeKey(secondInput.charAt(i));
}
}
await UrlbarTestUtils.promiseSearchComplete(window);
await waitForPauseImpression();
assertImpressionTelemetry([
{ reason: "pause" },
{ reason: "pause" },
{
interaction: showSearchTermsEnabled
? expectedForShowSearchTermsEnabled
: expectedForShowSearchTermsDisabled,
},
]);
});
}
await SpecialPowers.popPrefEnv();
}
}
);

View file

@ -0,0 +1,164 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Test impression telemetry with persisted search terms disabled.
// Allow more time for Mac machines so they don't time out in verify mode.
if (AppConstants.platform == "macosx") {
requestLongerTimeout(3);
}
/* import-globals-from head-glean.js */
Services.scriptloader.loadSubScript(
"chrome://mochitests/content/browser/browser/components/urlbar/tests/browser/head-glean.js",
this
);
add_setup(async function() {
await setup();
await SpecialPowers.pushPrefEnv({
set: [
["browser.urlbar.showSearchTerms.featureGate", false],
[
"browser.urlbar.searchEngagementTelemetry.pauseImpressionIntervalMs",
100,
],
],
});
});
add_task(async function interaction_persisted_search_terms() {
await doTest(async browser => {
await openPopup("x");
await waitForPauseImpression();
await doEnter();
await openPopup("x");
await waitForPauseImpression();
assertImpressionTelemetry([
{ reason: "pause" },
{ reason: "pause", interaction: "typed" },
]);
});
});
add_task(async function interaction_persisted_search_terms_restarted_refined() {
const testData = [
{
firstInput: "x",
// Just move the focus to the URL bar after engagement.
secondInput: null,
expected: "topsites",
},
{
firstInput: "x",
secondInput: "x",
expected: "typed",
},
{
firstInput: "x",
secondInput: "y",
expected: "typed",
},
{
firstInput: "x",
secondInput: "x y",
expected: "typed",
},
{
firstInput: "x y",
secondInput: "x",
expected: "typed",
},
];
for (const { firstInput, secondInput, expected } of testData) {
await doTest(async browser => {
await openPopup(firstInput);
await waitForPauseImpression();
await doEnter();
await UrlbarTestUtils.promisePopupOpen(window, () => {
EventUtils.synthesizeKey("l", { accelKey: true });
});
if (secondInput) {
for (let i = 0; i < secondInput.length; i++) {
EventUtils.synthesizeKey(secondInput.charAt(i));
}
}
await UrlbarTestUtils.promiseSearchComplete(window);
await waitForPauseImpression();
assertImpressionTelemetry([
{ reason: "pause" },
{ reason: "pause", interaction: expected },
]);
});
}
});
add_task(
async function interaction_persisted_search_terms_restarted_refined_via_abandonment() {
const testData = [
{
firstInput: "x",
// Just move the focus to the URL bar after blur.
secondInput: null,
expected: "returned",
},
{
firstInput: "x",
secondInput: "x",
expected: "returned",
},
{
firstInput: "x",
secondInput: "y",
expected: "restarted",
},
{
firstInput: "x",
secondInput: "x y",
expected: "refined",
},
{
firstInput: "x y",
secondInput: "x",
expected: "refined",
},
];
for (const { firstInput, secondInput, expected } of testData) {
await doTest(async browser => {
await openPopup("any search");
await waitForPauseImpression();
await doEnter();
await openPopup(firstInput);
await waitForPauseImpression();
await doBlur();
await UrlbarTestUtils.promisePopupOpen(window, () => {
EventUtils.synthesizeKey("l", { accelKey: true });
});
if (secondInput) {
for (let i = 0; i < secondInput.length; i++) {
EventUtils.synthesizeKey(secondInput.charAt(i));
}
}
await UrlbarTestUtils.promiseSearchComplete(window);
await waitForPauseImpression();
assertImpressionTelemetry([
{ reason: "pause" },
{ reason: "pause" },
{ reason: "pause", interaction: expected },
]);
});
}
}
);

View file

@ -0,0 +1,166 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Test impression telemetry with persisted search terms enabled.
// Allow more time for Mac machines so they don't time out in verify mode.
if (AppConstants.platform == "macosx") {
requestLongerTimeout(3);
}
/* import-globals-from head-glean.js */
Services.scriptloader.loadSubScript(
"chrome://mochitests/content/browser/browser/components/urlbar/tests/browser/head-glean.js",
this
);
add_setup(async function() {
await setup();
await SpecialPowers.pushPrefEnv({
set: [
["browser.urlbar.showSearchTerms.featureGate", true],
["browser.urlbar.showSearchTerms.enabled", true],
["browser.search.widget.inNavBar", false],
[
"browser.urlbar.searchEngagementTelemetry.pauseImpressionIntervalMs",
100,
],
],
});
});
add_task(async function interaction_persisted_search_terms() {
await doTest(async browser => {
await openPopup("x");
await waitForPauseImpression();
await doEnter();
await openPopup("x");
await waitForPauseImpression();
assertImpressionTelemetry([
{ reason: "pause" },
{ reason: "pause", interaction: "persisted_search_terms" },
]);
});
});
add_task(async function interaction_persisted_search_terms_restarted_refined() {
const testData = [
{
firstInput: "x",
// Just move the focus to the URL bar after engagement.
secondInput: null,
expected: "persisted_search_terms",
},
{
firstInput: "x",
secondInput: "x",
expected: "persisted_search_terms",
},
{
firstInput: "x",
secondInput: "y",
expected: "persisted_search_terms_restarted",
},
{
firstInput: "x",
secondInput: "x y",
expected: "persisted_search_terms_refined",
},
{
firstInput: "x y",
secondInput: "x",
expected: "persisted_search_terms_refined",
},
];
for (const { firstInput, secondInput, expected } of testData) {
await doTest(async browser => {
await openPopup(firstInput);
await waitForPauseImpression();
await doEnter();
await UrlbarTestUtils.promisePopupOpen(window, () => {
EventUtils.synthesizeKey("l", { accelKey: true });
});
if (secondInput) {
for (let i = 0; i < secondInput.length; i++) {
EventUtils.synthesizeKey(secondInput.charAt(i));
}
}
await UrlbarTestUtils.promiseSearchComplete(window);
await waitForPauseImpression();
assertImpressionTelemetry([
{ reason: "pause" },
{ reason: "pause", interaction: expected },
]);
});
}
});
add_task(
async function interaction_persisted_search_terms_restarted_refined_via_abandonment() {
const testData = [
{
firstInput: "x",
// Just move the focus to the URL bar after blur.
secondInput: null,
expected: "persisted_search_terms",
},
{
firstInput: "x",
secondInput: "x",
expected: "persisted_search_terms",
},
{
firstInput: "x",
secondInput: "y",
expected: "persisted_search_terms_restarted",
},
{
firstInput: "x",
secondInput: "x y",
expected: "persisted_search_terms_refined",
},
{
firstInput: "x y",
secondInput: "x",
expected: "persisted_search_terms_refined",
},
];
for (const { firstInput, secondInput, expected } of testData) {
await doTest(async browser => {
await openPopup("any search");
await waitForPauseImpression();
await doEnter();
await openPopup(firstInput);
await waitForPauseImpression();
await doBlur();
await UrlbarTestUtils.promisePopupOpen(window, () => {
EventUtils.synthesizeKey("l", { accelKey: true });
});
if (secondInput) {
for (let i = 0; i < secondInput.length; i++) {
EventUtils.synthesizeKey(secondInput.charAt(i));
}
}
await UrlbarTestUtils.promiseSearchComplete(window);
await waitForPauseImpression();
assertImpressionTelemetry([
{ reason: "pause" },
{ reason: "pause" },
{ reason: "pause", interaction: expected },
]);
});
}
}
);

0
browser/config/mozconfigs/win64/mingwclang Executable file → Normal file
View file

0
browser/config/mozconfigs/win64/nightly-fuzzing-asan Executable file → Normal file
View file

View file

@ -514,7 +514,6 @@ class EditCreditCard extends EditAutofillForm {
),
month: this._elements.form.querySelector("#cc-exp-month"),
year: this._elements.form.querySelector("#cc-exp-year"),
ccType: this._elements.form.querySelector("#cc-type"),
billingAddress: this._elements.form.querySelector("#billingAddressGUID"),
billingAddressRow: this._elements.form.querySelector(
".billingAddressRow"
@ -531,8 +530,6 @@ class EditCreditCard extends EditAutofillForm {
this._addresses = addresses;
this.generateBillingAddressOptions(preserveFieldValues);
if (!preserveFieldValues) {
// Re-populating the networks will reset the selected option.
this.populateNetworks();
// Re-generating the months will reset the selected option.
this.generateMonths();
// Re-generating the years will reset the selected option.
@ -591,23 +588,6 @@ class EditCreditCard extends EditAutofillForm {
}
}
populateNetworks() {
// Clear the list
this._elements.ccType.textContent = "";
let frag = document.createDocumentFragment();
// include an empty first option
frag.appendChild(new Option("", ""));
let supportedNetworks = FormAutofillUtils.getCreditCardNetworks();
for (let id of supportedNetworks) {
const option = new Option(undefined, id);
// autofill-card-network-amex, ..., autofill-card-network-visa
option.dataset.l10nId = `autofill-card-network-${id}`;
frag.appendChild(option);
}
this._elements.ccType.appendChild(frag);
}
generateBillingAddressOptions(preserveFieldValues) {
let billingAddressGUID;
if (preserveFieldValues && this._elements.billingAddress.value) {

View file

@ -44,11 +44,6 @@
<input id="cc-name" type="text" required="required"/>
<span data-l10n-id="autofill-card-name-on-card" class="label-text"/>
</label>
<label id="cc-type-container" class="container">
<select id="cc-type" required="required">
</select>
<span data-l10n-id="autofill-card-network" class="label-text"/>
</label>
<label id="cc-csc-container" class="container" hidden="hidden">
<!-- The CSC container will get filled in by forms that need a CSC (using csc-input.js) -->
</label>

View file

@ -12,6 +12,11 @@ ChromeUtils.defineModuleGetter(
"formAutofillStorage",
"resource://autofill/FormAutofillStorage.jsm"
);
ChromeUtils.defineModuleGetter(
this,
"AutofillTelemetry",
"resource://autofill/AutofillTelemetry.jsm"
);
class AutofillEditDialog {
constructor(subStorageName, elements, record) {
@ -148,11 +153,21 @@ class AutofillEditDialog {
// An interface to be inherited.
localizeDocument() {}
recordFormSubmit() {
let method = this._record?.guid ? "edit" : "add";
AutofillTelemetry.recordManageEvent(this.telemetryType, method);
}
}
class EditAddressDialog extends AutofillEditDialog {
telemetryType = AutofillTelemetry.ADDRESS;
constructor(elements, record) {
super("addresses", elements, record);
if (record) {
AutofillTelemetry.recordManageEvent(this.telemetryType, "show_entry");
}
}
localizeDocument() {
@ -169,11 +184,15 @@ class EditAddressDialog extends AutofillEditDialog {
this._elements.fieldContainer.buildFormObject(),
this._record ? this._record.guid : null
);
this.recordFormSubmit();
window.close();
}
}
class EditCreditCardDialog extends AutofillEditDialog {
telemetryType = AutofillTelemetry.CREDIT_CARD;
constructor(elements, record) {
elements.fieldContainer._elements.billingAddress.disabled = true;
super("creditCards", elements, record);
@ -182,7 +201,7 @@ class EditCreditCardDialog extends AutofillEditDialog {
this._onCCNumberFieldBlur.bind(this)
);
if (record) {
Services.telemetry.recordEvent("creditcard", "show_entry", "manage");
AutofillTelemetry.recordManageEvent(this.telemetryType, "show_entry");
}
}
@ -212,11 +231,7 @@ class EditCreditCardDialog extends AutofillEditDialog {
this._record ? this._record.guid : null
);
if (this._record?.guid) {
Services.telemetry.recordEvent("creditcard", "edit", "manage");
} else {
Services.telemetry.recordEvent("creditcard", "add", "manage");
}
this.recordFormSubmit();
window.close();
} catch (ex) {

View file

@ -19,6 +19,9 @@ const { XPCOMUtils } = ChromeUtils.importESModule(
const { FormAutofill } = ChromeUtils.import(
"resource://autofill/FormAutofill.jsm"
);
const { AutofillTelemetry } = ChromeUtils.import(
"resource://autofill/AutofillTelemetry.jsm"
);
ChromeUtils.defineESModuleGetters(this, {
CreditCard: "resource://gre/modules/CreditCard.sys.mjs",
@ -192,6 +195,10 @@ class ManageRecords {
Services.obs.addObserver(this, "formautofill-storage-changed");
// For testing only: notify record(s) has been removed
this._elements.records.dispatchEvent(new CustomEvent("RecordsRemoved"));
for (let i = 0; i < options.length; i++) {
AutofillTelemetry.recordManageEvent(this.telemetryType, "delete");
}
}
/**
@ -315,12 +322,15 @@ class ManageRecords {
}
class ManageAddresses extends ManageRecords {
telemetryType = AutofillTelemetry.ADDRESS;
constructor(elements) {
super("addresses", elements);
elements.add.setAttribute(
"search-l10n-ids",
FormAutofillUtils.EDIT_ADDRESS_L10N_IDS.join(",")
);
AutofillTelemetry.recordManageEvent(this.telemetryType, "show");
}
/**
@ -343,6 +353,8 @@ class ManageAddresses extends ManageRecords {
}
class ManageCreditCards extends ManageRecords {
telemetryType = AutofillTelemetry.CREDIT_CARD;
constructor(elements) {
super("creditCards", elements);
elements.add.setAttribute(
@ -350,9 +362,8 @@ class ManageCreditCards extends ManageRecords {
FormAutofillUtils.EDIT_CREDITCARD_L10N_IDS.join(",")
);
Services.telemetry.recordEvent("creditcard", "show", "manage");
this._isDecrypted = false;
AutofillTelemetry.recordManageEvent(this.telemetryType, "show");
}
/**
@ -451,13 +462,6 @@ class ManageCreditCards extends ManageRecords {
}
}
async removeRecords(options) {
await super.removeRecords(options);
for (let i = 0; i < options.length; i++) {
Services.telemetry.recordEvent("creditcard", "delete", "manage");
}
}
updateButtonsStates(selectedCount) {
super.updateButtonsStates(selectedCount);
}

View file

@ -33,6 +33,7 @@ elif CONFIG["MOZ_WIDGET_TOOLKIT"] == "windows":
]
BROWSER_CHROME_MANIFESTS += [
"test/browser/address/browser.ini",
"test/browser/browser.ini",
"test/browser/creditCard/browser.ini",
"test/browser/focus-leak/browser.ini",

View file

@ -6,7 +6,7 @@
display: grid;
grid-template-areas:
"cc-number cc-exp-month cc-exp-year"
"cc-name cc-type cc-csc"
"cc-name cc-csc ."
"billingAddressGUID billingAddressGUID billingAddressGUID";
grid-template-columns: 4fr 2fr 2fr;
grid-row-gap: var(--grid-column-row-gap);
@ -40,10 +40,6 @@
grid-area: cc-name;
}
#cc-type-container {
grid-area: cc-type;
}
#cc-csc-container {
grid-area: cc-csc;
}

View file

@ -0,0 +1,12 @@
[DEFAULT]
prefs =
extensions.formautofill.addresses.enabled=true
# lower the interval for event telemetry in the content process to update the parent process
toolkit.telemetry.ipcBatchTimeout=0
support-files =
../head.js
../../fixtures/autocomplete_address_basic.html
../../fixtures/without_autocomplete_address_basic.html
head_address.js
[browser_address_telemetry.js]

View file

@ -0,0 +1,681 @@
"use strict";
const { TelemetryTestUtils } = ChromeUtils.importESModule(
"resource://testing-common/TelemetryTestUtils.sys.mjs"
);
const { AddressTelemetry } = ChromeUtils.import(
"resource://autofill/AutofillTelemetry.jsm"
);
// Preference definitions
const ENABLED_PREF = ENABLED_AUTOFILL_ADDRESSES_PREF;
const AVAILABLE_PREF = AUTOFILL_ADDRESSES_AVAILABLE_PREF;
const CAPTURE_ENABLE_PREF = ENABLED_AUTOFILL_ADDRESSES_CAPTURE_PREF;
// Telemetry definitions
const EVENT_CATEGORY = "address";
const SCALAR_DETECTED_SECTION_COUNT =
"formautofill.addresses.detected_sections_count";
const SCALAR_SUBMITTED_SECTION_COUNT =
"formautofill.addresses.submitted_sections_count";
const SCALAR_AUTOFILL_PROFILE_COUNT =
"formautofill.addresses.autofill_profiles_count";
const HISTOGRAM_PROFILE_NUM_USES = "AUTOFILL_PROFILE_NUM_USES";
const HISTOGRAM_PROFILE_NUM_USES_KEY = "address";
// Autofill UI
const MANAGE_DIALOG_URL = MANAGE_ADDRESSES_DIALOG_URL;
const EDIT_DIALOG_URL = EDIT_ADDRESS_DIALOG_URL;
const DIALOG_SIZE = "width=600,height=400";
const MANAGE_RECORD_SELECTOR = "#addresses";
// Test specific definitions
const TEST_PROFILE = TEST_ADDRESS_1;
const TEST_PROFILE_1 = TEST_ADDRESS_1;
const TEST_PROFILE_2 = TEST_ADDRESS_2;
const TEST_PROFILE_3 = TEST_ADDRESS_3;
const TEST_FOCUS_NAME_FIELD = "given-name";
const TEST_FOCUS_NAME_FIELD_SELECTOR = "#" + TEST_FOCUS_NAME_FIELD;
// Used for tests that update address fields after filling
const TEST_NEW_VALUES = {
"#given-name": "Test User",
"#organization": "Sesame Street",
"#street-address": "123 Sesame Street",
"#tel": "1-345-345-3456",
};
const TEST_BASIC_ADDRESS_FORM_URL = ADDRESS_FORM_URL;
const TEST_BASIC_ADDRESS_FORM_WITHOUT_AC_URL = ADDRESS_FORM_WITHOUT_AUTOCOMPLETE_URL;
// This should be sync with the address fields that appear in TEST_BASIC_ADDRESS_FORM
const TEST_BASIC_ADDRESS_FORM_FIELDS = [
"street_address",
"address_level1",
"address_level2",
"postal_code",
"country",
"given_name",
"family_name",
"organization",
"email",
"tel",
];
function buildFormExtra(list, fields, fieldValue, defaultValue, aExtra = {}) {
let extra = {};
for (const field of list) {
if (aExtra[field]) {
extra[field] = aExtra[field];
} else {
extra[field] = fields.includes(field) ? fieldValue : defaultValue;
}
}
return extra;
}
/**
* Utility function to generate expected value for `address_form` and `address_form_ext`
* telemetry event.
*
* @param {string} method see `methods` in `address_form` event telemetry
* @param {object} defaultExtra default extra object, this will not be overwritten
* @param {object} fields address fields that will be set to `value` param
* @param {string} value value to set for fields list in `fields` argument
* @param {string} defaultValue value to set for address fields that are not listed in `fields` argument`
*/
function formArgs(
method,
defaultExtra,
fields = [],
value = undefined,
defaultValue = null
) {
if (["popup_shown", "filled_modified"].includes(method)) {
return [["address", method, "address_form", undefined, defaultExtra]];
}
let extra = buildFormExtra(
AddressTelemetry.SUPPORTED_FIELDS_IN_FORM,
fields,
value,
defaultValue,
defaultExtra
);
let extraExt = buildFormExtra(
AddressTelemetry.SUPPORTED_FIELDS_IN_FORM_EXT,
fields,
value,
defaultValue,
defaultExtra
);
// The order here should sync with AutofillTelemetry.
return [
["address", method, "address_form", undefined, extra],
["address", method, "address_form_ext", undefined, extraExt],
];
}
function getProfiles() {
return getAddresses();
}
async function assertTelemetry(expected_content, expected_parent) {
let snapshots;
info(
`Waiting for ${expected_content?.length ?? 0} content events and ` +
`${expected_parent?.length ?? 0} parent events`
);
await TestUtils.waitForCondition(
() => {
snapshots = Services.telemetry.snapshotEvents(
Ci.nsITelemetry.DATASET_PRERELEASE_CHANNELS,
false
);
return (
(snapshots.parent?.length ?? 0) >= (expected_parent?.length ?? 0) &&
(snapshots.content?.length ?? 0) >= (expected_content?.length ?? 0)
);
},
"Wait for telemetry to be collected",
100,
100
);
info(JSON.stringify(snapshots, null, 2));
if (expected_content !== undefined) {
expected_content = expected_content.map(
([category, method, object, value, extra]) => {
return { category, method, object, value, extra };
}
);
let clear = expected_parent === undefined;
TelemetryTestUtils.assertEvents(
expected_content,
{
category: EVENT_CATEGORY,
},
{ clear, process: "content" }
);
}
if (expected_parent !== undefined) {
expected_parent = expected_parent.map(
([category, method, object, value, extra]) => {
return { category, method, object, value, extra };
}
);
TelemetryTestUtils.assertEvents(
expected_parent,
{
category: EVENT_CATEGORY,
},
{ process: "parent" }
);
}
}
function _assertHistogram(snapshot, expectedNonZeroRanges) {
// Compute the actual ranges in the format { range1: value1, range2: value2 }.
let actualNonZeroRanges = {};
for (let [range, value] of Object.entries(snapshot.values)) {
if (value > 0) {
actualNonZeroRanges[range] = value;
}
}
// These are stringified to visualize the differences between the values.
Assert.equal(
JSON.stringify(actualNonZeroRanges),
JSON.stringify(expectedNonZeroRanges)
);
}
function assertKeyedHistogram(histogramId, key, expected) {
let snapshot = Services.telemetry
.getKeyedHistogramById(histogramId)
.snapshot();
if (expected == undefined) {
Assert.deepEqual(snapshot, {});
} else {
_assertHistogram(snapshot[key], expected);
}
}
async function openTabAndUseAutofillProfile(
idx,
profile,
{ closeTab = true, submitForm = true } = {}
) {
let tab = await BrowserTestUtils.openNewForegroundTab(
gBrowser,
TEST_BASIC_ADDRESS_FORM_URL
);
let browser = tab.linkedBrowser;
await openPopupOn(browser, "form " + TEST_FOCUS_NAME_FIELD_SELECTOR);
for (let i = 0; i <= idx; i++) {
await BrowserTestUtils.synthesizeKey("VK_DOWN", {}, browser);
}
await BrowserTestUtils.synthesizeKey("VK_RETURN", {}, browser);
await waitForAutofill(
browser,
TEST_FOCUS_NAME_FIELD_SELECTOR,
profile[TEST_FOCUS_NAME_FIELD]
);
await focusUpdateSubmitForm(
browser,
{
focusSelector: TEST_FOCUS_NAME_FIELD_SELECTOR,
newValues: {},
},
submitForm
);
if (!closeTab) {
return tab;
}
await BrowserTestUtils.removeTab(tab);
return null;
}
add_setup(async function() {
await SpecialPowers.pushPrefEnv({
set: [
[ENABLED_PREF, true],
[AVAILABLE_PREF, "on"],
[CAPTURE_ENABLE_PREF, true],
],
});
Services.telemetry.setEventRecordingEnabled(EVENT_CATEGORY, true);
Services.telemetry.clearEvents();
Services.telemetry.clearScalars();
registerCleanupFunction(() => {
Services.telemetry.setEventRecordingEnabled(EVENT_CATEGORY, false);
});
});
add_task(async function test_popup_opened() {
await setStorage(TEST_PROFILE);
await BrowserTestUtils.withNewTab(
{ gBrowser, url: TEST_BASIC_ADDRESS_FORM_URL },
async function(browser) {
const focusInput = TEST_FOCUS_NAME_FIELD_SELECTOR;
await openPopupOn(browser, focusInput);
// Clean up
await closePopup(browser);
}
);
const fields = TEST_BASIC_ADDRESS_FORM_FIELDS;
await assertTelemetry([
...formArgs("detected", {}, fields, "true", "false"),
...formArgs("popup_shown", { field_name: TEST_FOCUS_NAME_FIELD }),
]);
TelemetryTestUtils.assertScalar(
TelemetryTestUtils.getProcessScalars("content"),
SCALAR_DETECTED_SECTION_COUNT,
1,
"There should be 1 section detected."
);
TelemetryTestUtils.assertScalarUnset(
TelemetryTestUtils.getProcessScalars("content"),
SCALAR_SUBMITTED_SECTION_COUNT,
1
);
await removeAllRecords();
Services.telemetry.clearEvents();
Services.telemetry.clearScalars();
});
add_task(async function test_popup_opened_form_without_autocomplete() {
await setStorage(TEST_PROFILE);
await BrowserTestUtils.withNewTab(
{ gBrowser, url: TEST_BASIC_ADDRESS_FORM_WITHOUT_AC_URL },
async function(browser) {
const focusInput = TEST_FOCUS_NAME_FIELD_SELECTOR;
await openPopupOn(browser, focusInput);
await closePopup(browser);
}
);
const fields = TEST_BASIC_ADDRESS_FORM_FIELDS;
await assertTelemetry([
...formArgs("detected", {}, fields, "0", "false"),
...formArgs("popup_shown", { field_name: TEST_FOCUS_NAME_FIELD }),
]);
TelemetryTestUtils.assertScalar(
TelemetryTestUtils.getProcessScalars("content"),
SCALAR_DETECTED_SECTION_COUNT,
1,
"There should be 1 section detected."
);
TelemetryTestUtils.assertScalarUnset(
TelemetryTestUtils.getProcessScalars("content"),
SCALAR_SUBMITTED_SECTION_COUNT
);
await removeAllRecords();
Services.telemetry.clearEvents();
Services.telemetry.clearScalars();
});
add_task(async function test_submit_autofill_profile_new() {
await SpecialPowers.pushPrefEnv({
set: [["extensions.formautofill.firstTimeUse", true]],
});
async function test_per_command(
command,
idx,
useCount = {},
expectChanged = undefined
) {
await BrowserTestUtils.withNewTab(
{ gBrowser, url: TEST_BASIC_ADDRESS_FORM_URL },
async function(browser) {
let onPopupShown = waitForPopupShown();
let onChanged;
if (expectChanged !== undefined) {
onChanged = TestUtils.topicObserved("formautofill-storage-changed");
}
await focusUpdateSubmitForm(browser, {
focusSelector: TEST_FOCUS_NAME_FIELD_SELECTOR,
newValues: TEST_NEW_VALUES,
});
await onPopupShown;
await clickDoorhangerButton(command, idx);
if (expectChanged !== undefined) {
await onChanged;
TelemetryTestUtils.assertScalar(
TelemetryTestUtils.getProcessScalars("parent"),
SCALAR_AUTOFILL_PROFILE_COUNT,
expectChanged,
"There should be ${expectChanged} profile(s) stored."
);
}
}
);
assertKeyedHistogram(
HISTOGRAM_PROFILE_NUM_USES,
HISTOGRAM_PROFILE_NUM_USES_KEY,
useCount
);
await removeAllRecords();
}
Services.telemetry.clearEvents();
Services.telemetry.clearScalars();
Services.telemetry.getKeyedHistogramById(HISTOGRAM_PROFILE_NUM_USES).clear();
const fields = TEST_BASIC_ADDRESS_FORM_FIELDS;
let expected_content = [
...formArgs("detected", {}, fields, "true", "false"),
...formArgs("submitted", {}, fields, "user_filled", "unavailable"),
];
// FTU
await test_per_command(MAIN_BUTTON, undefined, { 1: 1 }, 1);
await assertTelemetry(expected_content, [
[EVENT_CATEGORY, "show", "capture_doorhanger"],
[EVENT_CATEGORY, "pref", "capture_doorhanger"],
]);
// Need to close preference tab
BrowserTestUtils.removeTab(gBrowser.selectedTab);
TelemetryTestUtils.assertScalar(
TelemetryTestUtils.getProcessScalars("content"),
SCALAR_DETECTED_SECTION_COUNT,
1,
"There should be 1 sections detected."
);
TelemetryTestUtils.assertScalar(
TelemetryTestUtils.getProcessScalars("content"),
SCALAR_SUBMITTED_SECTION_COUNT,
1,
"There should be 1 section submitted."
);
await removeAllRecords();
Services.telemetry.clearEvents();
Services.telemetry.clearScalars();
});
add_task(async function test_submit_autofill_profile_update() {
async function test_per_command(
command,
idx,
useCount = {},
expectChanged = undefined
) {
await setStorage(TEST_PROFILE);
let profiles = await getProfiles();
Assert.equal(profiles.length, 1, "1 entry in storage");
await BrowserTestUtils.withNewTab(
{ gBrowser, url: TEST_BASIC_ADDRESS_FORM_URL },
async function(browser) {
let onPopupShown = waitForPopupShown();
let onChanged;
if (expectChanged !== undefined) {
onChanged = TestUtils.topicObserved("formautofill-storage-changed");
}
await openPopupOn(browser, TEST_FOCUS_NAME_FIELD_SELECTOR);
await BrowserTestUtils.synthesizeKey("VK_DOWN", {}, browser);
await BrowserTestUtils.synthesizeKey("VK_RETURN", {}, browser);
await waitForAutofill(
browser,
TEST_FOCUS_NAME_FIELD_SELECTOR,
TEST_PROFILE[TEST_FOCUS_NAME_FIELD]
);
await focusUpdateSubmitForm(browser, {
focusSelector: TEST_FOCUS_NAME_FIELD_SELECTOR,
newValues: TEST_NEW_VALUES,
});
await onPopupShown;
await clickDoorhangerButton(command, idx);
if (expectChanged !== undefined) {
await onChanged;
TelemetryTestUtils.assertScalar(
TelemetryTestUtils.getProcessScalars("parent"),
SCALAR_AUTOFILL_PROFILE_COUNT,
expectChanged,
"There should be ${expectChanged} profile(s) stored."
);
}
}
);
assertKeyedHistogram(
HISTOGRAM_PROFILE_NUM_USES,
HISTOGRAM_PROFILE_NUM_USES_KEY,
useCount
);
SpecialPowers.clearUserPref(ENABLED_PREF);
await removeAllRecords();
}
Services.telemetry.clearEvents();
Services.telemetry.clearScalars();
Services.telemetry.getKeyedHistogramById(HISTOGRAM_PROFILE_NUM_USES).clear();
const fields = TEST_BASIC_ADDRESS_FORM_FIELDS;
let expected_content = [
...formArgs("detected", {}, fields, "true", "false"),
...formArgs("popup_shown", { field_name: TEST_FOCUS_NAME_FIELD }),
...formArgs("filled", {}, fields, "filled", "unavailable"),
...formArgs("filled_modified", { field_name: "given-name" }),
...formArgs("filled_modified", { field_name: "organization" }),
...formArgs("filled_modified", { field_name: "street-address" }),
...formArgs("filled_modified", { field_name: "tel" }),
...formArgs(
"submitted",
{
given_name: "user_filled",
organization: "user_filled",
street_address: "user_filled",
tel: "user_filled",
},
fields,
"autofilled",
"unavailable"
),
];
await test_per_command(MAIN_BUTTON, undefined, { 1: 1 }, 1);
await assertTelemetry(expected_content, [
[EVENT_CATEGORY, "show", "update_doorhanger"],
[EVENT_CATEGORY, "update", "update_doorhanger"],
]);
await test_per_command(SECONDARY_BUTTON, undefined, { 0: 1, 1: 1 }, 2);
await assertTelemetry(expected_content, [
[EVENT_CATEGORY, "show", "update_doorhanger"],
[EVENT_CATEGORY, "save", "update_doorhanger"],
]);
await removeAllRecords();
Services.telemetry.clearEvents();
Services.telemetry.clearScalars();
});
add_task(async function test_removingAutofillProfilesViaKeyboardDelete() {
await setStorage(TEST_PROFILE);
let win = window.openDialog(MANAGE_DIALOG_URL, null, DIALOG_SIZE);
await waitForFocusAndFormReady(win);
let selRecords = win.document.querySelector(MANAGE_RECORD_SELECTOR);
Assert.equal(selRecords.length, 1, "One entry");
EventUtils.synthesizeMouseAtCenter(selRecords.children[0], {}, win);
EventUtils.synthesizeKey("VK_DELETE", {}, win);
await BrowserTestUtils.waitForEvent(selRecords, "RecordsRemoved");
Assert.equal(selRecords.length, 0, "No entry left");
win.close();
await assertTelemetry(undefined, [
[EVENT_CATEGORY, "show", "manage"],
[EVENT_CATEGORY, "delete", "manage"],
]);
await removeAllRecords();
Services.telemetry.clearEvents();
Services.telemetry.clearScalars();
});
add_task(async function test_saveAutofillProfile() {
Services.telemetry.clearEvents();
await testDialog(EDIT_DIALOG_URL, win => {
// TODP: Default to US because the layout will be different
EventUtils.synthesizeKey("VK_TAB", {}, win);
EventUtils.synthesizeKey(TEST_PROFILE["given-name"], {}, win);
EventUtils.synthesizeKey("VK_TAB", {}, win);
EventUtils.synthesizeKey("VK_TAB", {}, win);
EventUtils.synthesizeKey(TEST_PROFILE["family-name"], {}, win);
EventUtils.synthesizeKey("VK_TAB", {}, win);
EventUtils.synthesizeKey(TEST_PROFILE["street-address"], {}, win);
EventUtils.synthesizeKey("VK_TAB", {}, win);
EventUtils.synthesizeKey(TEST_PROFILE["address-level2"], {}, win);
EventUtils.synthesizeKey("VK_TAB", {}, win);
EventUtils.synthesizeKey("VK_TAB", {}, win);
EventUtils.synthesizeKey(TEST_PROFILE["postal-code"], {}, win);
info("saving one entry");
win.document.querySelector("#save").click();
});
await assertTelemetry(undefined, [[EVENT_CATEGORY, "add", "manage"]]);
await removeAllRecords();
Services.telemetry.clearEvents();
Services.telemetry.clearScalars();
});
add_task(async function test_editAutofillProfile() {
Services.telemetry.clearEvents();
await setStorage(TEST_PROFILE);
let profiles = await getProfiles();
Assert.equal(profiles.length, 1, "1 entry in storage");
await testDialog(
EDIT_DIALOG_URL,
win => {
EventUtils.synthesizeKey("VK_TAB", {}, win);
EventUtils.synthesizeKey("VK_RIGHT", {}, win);
EventUtils.synthesizeKey("test", {}, win);
win.document.querySelector("#save").click();
},
{
record: profiles[0],
}
);
await assertTelemetry(undefined, [
[EVENT_CATEGORY, "show_entry", "manage"],
[EVENT_CATEGORY, "edit", "manage"],
]);
await removeAllRecords();
Services.telemetry.clearEvents();
Services.telemetry.clearScalars();
});
add_task(async function test_histogram() {
Services.telemetry.getKeyedHistogramById(HISTOGRAM_PROFILE_NUM_USES).clear();
await setStorage(TEST_PROFILE_1, TEST_PROFILE_2, TEST_PROFILE_3);
let profiles = await getProfiles();
Assert.equal(profiles.length, 3, "3 entry in storage");
assertKeyedHistogram(
HISTOGRAM_PROFILE_NUM_USES,
HISTOGRAM_PROFILE_NUM_USES_KEY,
{ 0: 3 }
);
await openTabAndUseAutofillProfile(0, TEST_PROFILE_1);
assertKeyedHistogram(
HISTOGRAM_PROFILE_NUM_USES,
HISTOGRAM_PROFILE_NUM_USES_KEY,
{ 0: 2, 1: 1 }
);
await openTabAndUseAutofillProfile(1, TEST_PROFILE_2);
assertKeyedHistogram(
HISTOGRAM_PROFILE_NUM_USES,
HISTOGRAM_PROFILE_NUM_USES_KEY,
{ 0: 1, 1: 2 }
);
await openTabAndUseAutofillProfile(0, TEST_PROFILE_2);
assertKeyedHistogram(
HISTOGRAM_PROFILE_NUM_USES,
HISTOGRAM_PROFILE_NUM_USES_KEY,
{ 0: 1, 1: 1, 2: 1 }
);
await openTabAndUseAutofillProfile(1, TEST_PROFILE_1);
assertKeyedHistogram(
HISTOGRAM_PROFILE_NUM_USES,
HISTOGRAM_PROFILE_NUM_USES_KEY,
{ 0: 1, 2: 2 }
);
await openTabAndUseAutofillProfile(2, TEST_PROFILE_3);
assertKeyedHistogram(
HISTOGRAM_PROFILE_NUM_USES,
HISTOGRAM_PROFILE_NUM_USES_KEY,
{ 1: 1, 2: 2 }
);
await removeAllRecords();
assertKeyedHistogram(
HISTOGRAM_PROFILE_NUM_USES,
HISTOGRAM_PROFILE_NUM_USES_KEY,
undefined
);
Services.telemetry.clearEvents();
Services.telemetry.clearScalars();
});
add_task(async function test_clear_autofill_profile_autofill() {
// Address does not have clear pref. Keep the test so we know we should implement
// the test if we support clearing address via autocomplete.
Assert.ok(true);
});

View file

@ -0,0 +1 @@
/* import-globals-from ../head.js */

View file

@ -21,6 +21,8 @@ skip-if = ((os == "mac") || (os == 'linux') || (os == 'win'))
skip-if = ((!debug && os == "mac") || (os == 'linux') || (os == 'win'))
[browser_creditCard_heuristics.js]
skip-if = apple_silicon && !debug # Bug 1714221
[browser_creditCard_submission_autodetect_type.js]
skip-if = apple_silicon && !debug
[browser_creditCard_submission_normalized.js]
skip-if = apple_silicon && !debug
[browser_editCreditCardDialog.js]

View file

@ -57,7 +57,7 @@ add_task(async function test_submit_creditCard_saved() {
focusSelector: "#cc-name",
newValues: {
"#cc-name": "User 1",
"#cc-number": "5038146897157463",
"#cc-number": "5577000055770004",
"#cc-exp-month": "12",
"#cc-exp-year": "2017",
"#cc-type": "mastercard",
@ -918,7 +918,6 @@ add_task(async function test_submit_third_party_creditCard_logo() {
add_task(async function test_update_third_party_creditCard_logo() {
const amexCard = {
"cc-number": "374542158116607",
"cc-type": "amex",
"cc-name": "John Doe",
};
@ -1070,7 +1069,6 @@ add_task(async function test_save_panel_spaces_in_cc_number_logo() {
add_task(async function test_update_panel_with_spaces_in_cc_number_logo() {
const amexCard = {
"cc-number": "374 54215 8116607",
"cc-type": "amex",
"cc-name": "John Doe",
};

View file

@ -0,0 +1,110 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
add_task(async function test_autodetect_credit_not_set() {
await SpecialPowers.pushPrefEnv({
set: [[CREDITCARDS_USED_STATUS_PREF, 0]],
});
const testCard = {
"cc-name": "John Doe",
"cc-number": "4012888888881881",
"cc-exp-month": "06",
"cc-exp-year": "2044",
};
const expectedData = {
...testCard,
...{ "cc-type": "visa" },
};
let onChanged = waitForStorageChangedEvents("add");
await BrowserTestUtils.withNewTab(
{ gBrowser, url: CREDITCARD_FORM_URL },
async function(browser) {
let promiseShown = waitForPopupShown();
await focusUpdateSubmitForm(browser, {
focusSelector: "#cc-name",
newValues: {
"#cc-name": testCard["cc-name"],
"#cc-number": testCard["cc-number"],
"#cc-exp-month": testCard["cc-exp-month"],
"#cc-exp-year": testCard["cc-exp-year"],
"#cc-type": testCard["cc-type"],
},
});
await promiseShown;
await clickDoorhangerButton(MAIN_BUTTON);
}
);
await onChanged;
let creditCards = await getCreditCards();
let savedCreditCard = creditCards[0];
let decryptedNumber = await OSKeyStore.decrypt(
savedCreditCard["cc-number-encrypted"]
);
savedCreditCard["cc-number"] = decryptedNumber;
for (let key in testCard) {
let expected = expectedData[key];
let actual = savedCreditCard[key];
Assert.equal(expected, actual, `${key} should match`);
}
await removeAllRecords();
});
add_task(async function test_autodetect_credit_overwrite() {
await SpecialPowers.pushPrefEnv({
set: [[CREDITCARDS_USED_STATUS_PREF, 0]],
});
const testCard = {
"cc-name": "John Doe",
"cc-number": "4012888888881881",
"cc-exp-month": "06",
"cc-exp-year": "2044",
"cc-type": "master", // Wrong credit card type
};
const expectedData = {
...testCard,
...{ "cc-type": "visa" },
};
let onChanged = waitForStorageChangedEvents("add");
await BrowserTestUtils.withNewTab(
{ gBrowser, url: CREDITCARD_FORM_URL },
async function(browser) {
let promiseShown = waitForPopupShown();
await focusUpdateSubmitForm(browser, {
focusSelector: "#cc-name",
newValues: {
"#cc-name": testCard["cc-name"],
"#cc-number": testCard["cc-number"],
"#cc-exp-month": testCard["cc-exp-month"],
"#cc-exp-year": testCard["cc-exp-year"],
"#cc-type": testCard["cc-type"],
},
});
await promiseShown;
await clickDoorhangerButton(MAIN_BUTTON);
}
);
await onChanged;
let creditCards = await getCreditCards();
let savedCreditCard = creditCards[0];
let decryptedNumber = await OSKeyStore.decrypt(
savedCreditCard["cc-number-encrypted"]
);
savedCreditCard["cc-number"] = decryptedNumber;
for (let key in testCard) {
let expected = expectedData[key];
let actual = savedCreditCard[key];
Assert.equal(expected, actual, `${key} should match`);
}
await removeAllRecords();
});

View file

@ -3,9 +3,6 @@
const { TelemetryTestUtils } = ChromeUtils.importESModule(
"resource://testing-common/TelemetryTestUtils.sys.mjs"
);
const { CreditCardTelemetry } = ChromeUtils.import(
"resource://autofill/FormAutofillTelemetryUtils.jsm"
);
const CC_NUM_USES_HISTOGRAM = "CREDITCARD_NUM_USES";
@ -19,9 +16,14 @@ function ccFormArgsv2(method, extra) {
function buildccFormv2Extra(extra, defaultValue) {
let defaults = {};
for (const field of Object.values(
CreditCardTelemetry.CC_FORM_V2_SUPPORTED_FIELDS
)) {
for (const field of [
"cc_name",
"cc_number",
"cc_type",
"cc_exp",
"cc_exp_month",
"cc_exp_year",
]) {
defaults[field] = defaultValue;
}
@ -42,6 +44,7 @@ async function assertTelemetry(expected_content, expected_parent) {
Ci.nsITelemetry.DATASET_PRERELEASE_CHANNELS,
false
);
return (
(snapshots.parent?.length ?? 0) >= (expected_parent?.length ?? 0) &&
(snapshots.content?.length ?? 0) >= (expected_content?.length ?? 0)
@ -177,10 +180,10 @@ add_task(async function test_popup_opened() {
);
await assertTelemetry([
ccFormArgsv1("detected"),
ccFormArgsv2("detected", buildccFormv2Extra({ cc_exp: "false" }, "true")),
ccFormArgsv1("popup_shown"),
ccFormArgsv1("detected"),
ccFormArgsv2("popup_shown", { field_name: "cc-number" }),
ccFormArgsv1("popup_shown"),
]);
TelemetryTestUtils.assertScalar(
@ -228,13 +231,13 @@ add_task(async function test_popup_opened_form_without_autocomplete() {
);
await assertTelemetry([
ccFormArgsv1("detected"),
ccFormArgsv2(
"detected",
buildccFormv2Extra({ cc_number: "1", cc_name: "1", cc_exp: "false" }, "0")
),
ccFormArgsv1("popup_shown"),
ccFormArgsv1("detected"),
ccFormArgsv2("popup_shown", { field_name: "cc-number" }),
ccFormArgsv1("popup_shown"),
]);
TelemetryTestUtils.assertScalar(
@ -281,10 +284,10 @@ add_task(
);
await assertTelemetry([
ccFormArgsv1("detected"),
ccFormArgsv2("detected", buildccFormv2Extra({ cc_number: "1" }, "false")),
ccFormArgsv1("popup_shown"),
ccFormArgsv1("detected"),
ccFormArgsv2("popup_shown", { field_name: "cc-number" }),
ccFormArgsv1("popup_shown"),
]);
// Then click on the cc-name field of the form that doesn't have a cc-number field
@ -298,7 +301,6 @@ add_task(
);
await assertTelemetry([
ccFormArgsv1("detected"),
ccFormArgsv2(
"detected",
buildccFormv2Extra(
@ -306,8 +308,9 @@ add_task(
"false"
)
),
ccFormArgsv1("popup_shown"),
ccFormArgsv1("detected"),
ccFormArgsv2("popup_shown", { field_name: "cc-name" }),
ccFormArgsv1("popup_shown"),
]);
TelemetryTestUtils.assertScalar(
@ -343,7 +346,10 @@ add_task(async function test_submit_creditCard_new() {
{ gBrowser, url: CREDITCARD_FORM_URL },
async function(browser) {
let onPopupShown = waitForPopupShown();
let onChanged = TestUtils.topicObserved("formautofill-storage-changed");
let onChanged;
if (expectChanged !== undefined) {
onChanged = TestUtils.topicObserved("formautofill-storage-changed");
}
await focusUpdateSubmitForm(browser, {
focusSelector: "#cc-name",
@ -381,18 +387,18 @@ add_task(async function test_submit_creditCard_new() {
Services.telemetry.getHistogramById(CC_NUM_USES_HISTOGRAM).clear();
let expected_content = [
ccFormArgsv1("detected"),
ccFormArgsv2("detected", buildccFormv2Extra({ cc_exp: "false" }, "true")),
ccFormArgsv1("detected"),
ccFormArgsv2(
"submitted",
buildccFormv2Extra({ cc_exp: "unavailable" }, "user_filled")
),
ccFormArgsv1("submitted", {
// 5 fields plus submit button
fields_not_auto: "6",
fields_auto: "0",
fields_modified: "0",
}),
ccFormArgsv2(
"submitted",
buildccFormv2Extra({ cc_exp: "unavailable" }, "user_filled")
),
];
await test_per_command(MAIN_BUTTON, undefined, { 1: 1 }, 1);
await assertTelemetry(expected_content, [
@ -447,7 +453,7 @@ add_task(async function test_submit_creditCard_autofill() {
await setStorage(TEST_CREDIT_CARD_1);
let creditCards = await getCreditCards();
is(creditCards.length, 1, "1 credit card in storage");
Assert.equal(creditCards.length, 1, "1 credit card in storage");
await openTabAndUseCreditCard(0, TEST_CREDIT_CARD_1);
@ -460,24 +466,24 @@ add_task(async function test_submit_creditCard_autofill() {
await assertTelemetry(
[
ccFormArgsv1("detected"),
ccFormArgsv2("detected", buildccFormv2Extra({ cc_exp: "false" }, "true")),
ccFormArgsv1("popup_shown"),
ccFormArgsv1("detected"),
ccFormArgsv2("popup_shown", { field_name: "cc-name" }),
ccFormArgsv1("filled"),
ccFormArgsv1("popup_shown"),
ccFormArgsv2(
"filled",
buildccFormv2Extra({ cc_exp: "unavailable" }, "filled")
),
ccFormArgsv1("filled"),
ccFormArgsv2(
"submitted",
buildccFormv2Extra({ cc_exp: "unavailable" }, "autofilled")
),
ccFormArgsv1("submitted", {
fields_not_auto: "3",
fields_auto: "5",
fields_modified: "0",
}),
ccFormArgsv2(
"submitted",
buildccFormv2Extra({ cc_exp: "unavailable" }, "autofilled")
),
],
[]
);
@ -510,14 +516,17 @@ add_task(async function test_submit_creditCard_update() {
await setStorage(TEST_CREDIT_CARD_1);
let creditCards = await getCreditCards();
is(creditCards.length, 1, "1 credit card in storage");
Assert.equal(creditCards.length, 1, "1 credit card in storage");
let osKeyStoreLoginShown = OSKeyStoreTestUtils.waitForOSKeyStoreLogin(true);
await BrowserTestUtils.withNewTab(
{ gBrowser, url: CREDITCARD_FORM_URL },
async function(browser) {
let onPopupShown = waitForPopupShown();
let onChanged = TestUtils.topicObserved("formautofill-storage-changed");
let onChanged;
if (expectChanged !== undefined) {
onChanged = TestUtils.topicObserved("formautofill-storage-changed");
}
await openPopupOn(browser, "form #cc-name");
await BrowserTestUtils.synthesizeKey("VK_DOWN", {}, browser);
@ -556,22 +565,17 @@ add_task(async function test_submit_creditCard_update() {
Services.telemetry.getHistogramById(CC_NUM_USES_HISTOGRAM).clear();
let expected_content = [
ccFormArgsv1("detected"),
ccFormArgsv2("detected", buildccFormv2Extra({ cc_exp: "false" }, "true")),
ccFormArgsv1("popup_shown"),
ccFormArgsv1("detected"),
ccFormArgsv2("popup_shown", { field_name: "cc-name" }),
ccFormArgsv1("filled"),
ccFormArgsv1("popup_shown"),
ccFormArgsv2(
"filled",
buildccFormv2Extra({ cc_exp: "unavailable" }, "filled")
),
ccFormArgsv1("filled_modified", { field_name: "cc-exp-year" }),
ccFormArgsv1("filled"),
ccFormArgsv2("filled_modified", { field_name: "cc-exp-year" }),
ccFormArgsv1("submitted", {
fields_not_auto: "3",
fields_auto: "5",
fields_modified: "1",
}),
ccFormArgsv1("filled_modified", { field_name: "cc-exp-year" }),
ccFormArgsv2(
"submitted",
buildccFormv2Extra(
@ -579,6 +583,11 @@ add_task(async function test_submit_creditCard_update() {
"autofilled"
)
),
ccFormArgsv1("submitted", {
fields_not_auto: "3",
fields_auto: "5",
fields_modified: "1",
}),
];
await test_per_command(MAIN_BUTTON, undefined, { 1: 1 }, 1);
@ -620,12 +629,12 @@ add_task(async function test_removingCreditCardsViaKeyboardDelete() {
let selRecords = win.document.querySelector(TEST_SELECTORS.selRecords);
is(selRecords.length, 1, "One credit card");
Assert.equal(selRecords.length, 1, "One credit card");
EventUtils.synthesizeMouseAtCenter(selRecords.children[0], {}, win);
EventUtils.synthesizeKey("VK_DELETE", {}, win);
await BrowserTestUtils.waitForEvent(selRecords, "RecordsRemoved");
is(selRecords.length, 0, "No credit cards left");
Assert.equal(selRecords.length, 0, "No credit cards left");
win.close();
@ -663,8 +672,6 @@ add_task(async function test_saveCreditCard() {
EventUtils.synthesizeKey("VK_TAB", {}, win);
EventUtils.synthesizeKey(TEST_CREDIT_CARD_1["cc-name"], {}, win);
EventUtils.synthesizeKey("VK_TAB", {}, win);
EventUtils.synthesizeKey(TEST_CREDIT_CARD_1["cc-type"], {}, win);
EventUtils.synthesizeKey("VK_TAB", {}, win);
EventUtils.synthesizeKey("VK_TAB", {}, win);
info("saving credit card");
EventUtils.synthesizeKey("VK_RETURN", {}, win);
@ -686,14 +693,13 @@ add_task(async function test_editCreditCard() {
await setStorage(TEST_CREDIT_CARD_1);
let creditCards = await getCreditCards();
is(creditCards.length, 1, "only one credit card is in storage");
Assert.equal(creditCards.length, 1, "only one credit card is in storage");
await testDialog(
EDIT_CREDIT_CARD_DIALOG_URL,
win => {
EventUtils.synthesizeKey("VK_TAB", {}, win);
EventUtils.synthesizeKey("VK_TAB", {}, win);
EventUtils.synthesizeKey("VK_TAB", {}, win);
EventUtils.synthesizeKey("VK_TAB", {}, win);
EventUtils.synthesizeKey("VK_RIGHT", {}, win);
EventUtils.synthesizeKey("test", {}, win);
win.document.querySelector("#save").click();
@ -729,7 +735,7 @@ add_task(async function test_histogram() {
await setStorage(TEST_CREDIT_CARD_1, TEST_CREDIT_CARD_2, TEST_CREDIT_CARD_5);
let creditCards = await getCreditCards();
is(creditCards.length, 3, "3 credit cards in storage");
Assert.equal(creditCards.length, 3, "3 credit cards in storage");
assertHistogram(CC_NUM_USES_HISTOGRAM, {
0: 3,
@ -793,7 +799,7 @@ add_task(async function test_clear_creditCard_autofill() {
await setStorage(TEST_CREDIT_CARD_1);
let creditCards = await getCreditCards();
is(creditCards.length, 1, "1 credit card in storage");
Assert.equal(creditCards.length, 1, "1 credit card in storage");
let tab = await openTabAndUseCreditCard(0, TEST_CREDIT_CARD_1, {
closeTab: false,
@ -801,15 +807,15 @@ add_task(async function test_clear_creditCard_autofill() {
});
let expected_content = [
ccFormArgsv1("detected"),
ccFormArgsv2("detected", buildccFormv2Extra({ cc_exp: "false" }, "true")),
ccFormArgsv1("popup_shown"),
ccFormArgsv1("detected"),
ccFormArgsv2("popup_shown", { field_name: "cc-name" }),
ccFormArgsv1("filled"),
ccFormArgsv1("popup_shown"),
ccFormArgsv2(
"filled",
buildccFormv2Extra({ cc_exp: "unavailable" }, "filled")
),
ccFormArgsv1("filled"),
];
await assertTelemetry(expected_content, []);
Services.telemetry.clearEvents();
@ -825,8 +831,8 @@ add_task(async function test_clear_creditCard_autofill() {
await popupshown;
expected_content = [
ccFormArgsv1("popup_shown"),
ccFormArgsv2("popup_shown", { field_name: "cc-number" }),
ccFormArgsv1("popup_shown"),
];
await assertTelemetry(expected_content, []);
Services.telemetry.clearEvents();
@ -836,21 +842,21 @@ add_task(async function test_clear_creditCard_autofill() {
await BrowserTestUtils.synthesizeKey("KEY_Enter", {}, browser);
expected_content = [
ccFormArgsv1("filled_modified", { field_name: "cc-name" }),
ccFormArgsv2("filled_modified", { field_name: "cc-name" }),
ccFormArgsv1("filled_modified", { field_name: "cc-number" }),
ccFormArgsv1("filled_modified", { field_name: "cc-name" }),
ccFormArgsv2("filled_modified", { field_name: "cc-number" }),
ccFormArgsv1("filled_modified", { field_name: "cc-exp-month" }),
ccFormArgsv1("filled_modified", { field_name: "cc-number" }),
ccFormArgsv2("filled_modified", { field_name: "cc-exp-month" }),
ccFormArgsv1("filled_modified", { field_name: "cc-exp-year" }),
ccFormArgsv1("filled_modified", { field_name: "cc-exp-month" }),
ccFormArgsv2("filled_modified", { field_name: "cc-exp-year" }),
ccFormArgsv1("filled_modified", { field_name: "cc-type" }),
ccFormArgsv1("filled_modified", { field_name: "cc-exp-year" }),
ccFormArgsv2("filled_modified", { field_name: "cc-type" }),
ccFormArgsv1("filled_modified", { field_name: "cc-type" }),
ccFormArgsv2("cleared", { field_name: "cc-number" }),
// popup is shown again because when the field is cleared and is focused,
// we automatically triggers the popup.
ccFormArgsv1("popup_shown"),
ccFormArgsv2("popup_shown", { field_name: "cc-number" }),
ccFormArgsv1("popup_shown"),
];
await assertTelemetry(expected_content, []);

View file

@ -49,8 +49,6 @@ add_task(async function test_saveCreditCard() {
EventUtils.synthesizeKey("VK_TAB", {}, win);
EventUtils.synthesizeKey(TEST_CREDIT_CARD_1["cc-name"], {}, win);
EventUtils.synthesizeKey("VK_TAB", {}, win);
EventUtils.synthesizeKey(TEST_CREDIT_CARD_1["cc-type"], {}, win);
EventUtils.synthesizeKey("VK_TAB", {}, win);
EventUtils.synthesizeKey("VK_TAB", {}, win);
info("saving credit card");
EventUtils.synthesizeKey("VK_RETURN", {}, win);
@ -87,9 +85,6 @@ add_task(async function test_saveCreditCardWithMaxYear() {
EventUtils.synthesizeKey("VK_TAB", {}, win);
EventUtils.synthesizeKey(TEST_CREDIT_CARD_2["cc-name"], {}, win);
EventUtils.synthesizeKey("VK_TAB", {}, win);
EventUtils.synthesizeKey(TEST_CREDIT_CARD_1["cc-type"], {}, win);
EventUtils.synthesizeKey("VK_TAB", {}, win);
EventUtils.synthesizeKey("VK_TAB", {}, win);
info("saving credit card");
EventUtils.synthesizeKey("VK_RETURN", {}, win);
});
@ -133,8 +128,6 @@ add_task(async function test_saveCreditCardWithBillingAddress() {
EventUtils.synthesizeKey("VK_TAB", {}, win);
EventUtils.synthesizeKey(TEST_CREDIT_CARD["cc-name"], {}, win);
EventUtils.synthesizeKey("VK_TAB", {}, win);
EventUtils.synthesizeKey(TEST_CREDIT_CARD["cc-type"], {}, win);
EventUtils.synthesizeKey("VK_TAB", {}, win);
EventUtils.synthesizeKey(billingAddress["given-name"], {}, win);
EventUtils.synthesizeKey("VK_TAB", {}, win);
info("saving credit card");
@ -271,54 +264,6 @@ add_task(async function test_addInvalidCreditCard() {
is(creditCards.length, 0, "Credit card storage is empty");
});
add_task(async function test_editCardWithInvalidNetwork() {
const TEST_CREDIT_CARD = Object.assign({}, TEST_CREDIT_CARD_2, {
"cc-type": "asiv",
});
await setStorage(TEST_CREDIT_CARD);
let creditCards = await getCreditCards();
is(creditCards.length, 1, "one credit card in storage");
is(
creditCards[0]["cc-type"],
TEST_CREDIT_CARD["cc-type"],
"Check saved cc-type"
);
await testDialog(
EDIT_CREDIT_CARD_DIALOG_URL,
win => {
EventUtils.synthesizeKey("VK_TAB", {}, win);
EventUtils.synthesizeKey("VK_TAB", {}, win);
EventUtils.synthesizeKey("VK_TAB", {}, win);
EventUtils.synthesizeKey("VK_TAB", {}, win);
EventUtils.synthesizeKey("VK_RIGHT", {}, win);
EventUtils.synthesizeKey("test", {}, win);
win.document.querySelector("#save").click();
},
{
record: creditCards[0],
}
);
ok(true, "Edit credit card dialog is closed");
creditCards = await getCreditCards();
is(creditCards.length, 1, "only one credit card is in storage");
is(
creditCards[0]["cc-name"],
TEST_CREDIT_CARD["cc-name"] + "test",
"cc name changed"
);
is(
creditCards[0]["cc-type"],
"visa",
"unknown cc-type removed and next autodetected to visa upon manual save"
);
await removeCreditCards([creditCards[0].guid]);
creditCards = await getCreditCards();
is(creditCards.length, 0, "Credit card storage is empty");
});
add_task(async function test_editInvalidCreditCardNumber() {
await setStorage(TEST_ADDRESS_4);
let addresses = await getAddresses();

View file

@ -189,10 +189,7 @@ add_task(async function test_showCreditCardIcons() {
set: [["privacy.reduceTimerPrecision", false]],
});
await setStorage(TEST_CREDIT_CARD_1);
let unknownCard = Object.assign({}, TEST_CREDIT_CARD_3, {
"cc-type": "gringotts",
});
await setStorage(unknownCard);
await setStorage(TEST_CREDIT_CARD_3);
let win = window.openDialog(
MANAGE_CREDIT_CARDS_DIALOG_URL,
@ -216,7 +213,7 @@ add_task(async function test_showCreditCardIcons() {
is(
option0.getAttribute("cc-type"),
"gringotts",
"mastercard",
"Option has the expected cc-type"
);
is(

View file

@ -24,6 +24,14 @@ const PRIVACY_PREF_URL = "about:preferences#privacy";
const HTTP_TEST_PATH = "/browser/browser/extensions/formautofill/test/browser/";
const BASE_URL = "http://mochi.test:8888" + HTTP_TEST_PATH;
const FORM_URL = BASE_URL + "autocomplete_basic.html";
const ADDRESS_FORM_URL =
"https://example.org" +
HTTP_TEST_PATH +
"address/autocomplete_address_basic.html";
const ADDRESS_FORM_WITHOUT_AUTOCOMPLETE_URL =
"https://example.org" +
HTTP_TEST_PATH +
"address/without_autocomplete_address_basic.html";
const CREDITCARD_FORM_URL =
"https://example.org" +
HTTP_TEST_PATH +
@ -78,11 +86,13 @@ const TEST_ADDRESS_1 = {
};
const TEST_ADDRESS_2 = {
"given-name": "Anonymouse",
"street-address": "Some Address",
country: "US",
};
const TEST_ADDRESS_3 = {
"given-name": "John",
"street-address": "Other Address",
"postal-code": "12345",
};
@ -96,6 +106,8 @@ const TEST_ADDRESS_4 = {
email: "timbl@w3.org",
};
// TODO: Number of field less than AUTOFILL_FIELDS_THRESHOLD
// need to confirm whether this is intentional
const TEST_ADDRESS_5 = {
tel: "+16172535702",
};
@ -148,7 +160,6 @@ const TEST_CREDIT_CARD_1 = {
"cc-number": "4111111111111111",
"cc-exp-month": 4,
"cc-exp-year": new Date().getFullYear(),
"cc-type": "visa",
};
const TEST_CREDIT_CARD_2 = {
@ -156,25 +167,21 @@ const TEST_CREDIT_CARD_2 = {
"cc-number": "4929001587121045",
"cc-exp-month": 12,
"cc-exp-year": new Date().getFullYear() + 10,
"cc-type": "visa",
};
const TEST_CREDIT_CARD_3 = {
"cc-number": "5103059495477870",
"cc-exp-month": 1,
"cc-exp-year": 2000,
"cc-type": "mastercard",
};
const TEST_CREDIT_CARD_4 = {
"cc-number": "5105105105105100",
"cc-type": "mastercard",
};
const TEST_CREDIT_CARD_5 = {
"cc-name": "Chris P. Bacon",
"cc-number": "4012888888881881",
"cc-type": "visa",
};
const MAIN_BUTTON = "button";

View file

@ -0,0 +1,26 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Form Autofill Address Demo Page</title>
</head>
<body>
<h1>Form Autofill Address Demo Page</h1>
<form id="form">
<p><label>givenname: <input type="text" id="given-name" name="given-name" autocomplete="given-name" /></label></p>
<p><label>familyname: <input type="text" id="family-name" name="family-name" autocomplete="family-name" /></label></p>
<p><label>organization: <input type="text" id="organization" name="organization" autocomplete="organization" /></label></p>
<p><label>streetAddress: <input type="text" id="street-address" name="street-address" autocomplete="street-address" /></label></p>
<p><label>addressLevel2: <input type="text" id="address-level2" name="address-level2" autocomplete="address-level2" /></label></p>
<p><label>addressLevel1: <input type="text" id="address-level1" name="address-level1" autocomplete="address-level1" /></label></p>
<p><label>postalCode: <input type="text" id="postal-code" name="postal-code" autocomplete="postal-code" /></label></p>
<p><label>country: <input type="text" id="country" name="country" autocomplete="country" /></label></p>
<p><label>tel: <input type="text" id="tel" name="tel" autocomplete="tel" /></label></p>
<p><label>email: <input type="text" id="email" name="email" autocomplete="email" /></label></p>
<p>
<input type="submit"/>
<button type="reset">Reset</button>
</p>
</form>
</body>
</html>

View file

@ -0,0 +1,26 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Form Autofill Address Demo Page</title>
</head>
<body>
<h1>Form Autofill Address Demo Page (without autocomplete attribute)</h1>
<form id="form">
<p><label>givenname: <input type="text" id="given-name" name="given-name"/></label></p>
<p><label>familyname: <input type="text" id="family-name" name="family-name"/></label></p>
<p><label>organization: <input type="text" id="organization" name="organization"/></label></p>
<p><label>streetAddress: <input type="text" id="street-address" name="street-address"/></label></p>
<p><label>addressLevel2: <input type="text" id="address-level2" name="address-level2"/></label></p>
<p><label>addressLevel1: <input type="text" id="address-level1" name="address-level1"/></label></p>
<p><label>postalCode: <input type="text" id="postal-code" name="postal-code"/></label></p>
<p><label>country: <input type="text" id="country" name="country"/></label></p>
<p><label>tel: <input type="text" id="tel" name="tel"/></label></p>
<p><label>email: <input type="text" id="email" name="email"/></label></p>
<p>
<input type="submit"/>
<button type="reset">Reset</button>
</p>
</form>
</body>
</html>

View file

@ -20,13 +20,11 @@ const MOCK_STORAGE = [{
"cc-number": "4929001587121045",
"cc-exp-month": 4,
"cc-exp-year": 2017,
"cc-type": "visa",
}, {
"cc-name": "Timothy Berners-Lee",
"cc-number": "5103059495477870",
"cc-exp-month": 12,
"cc-exp-year": 2022,
"cc-type": "mastercard",
}];
const reducedMockRecord = {

View file

@ -12,10 +12,14 @@ const { CreditCard } = ChromeUtils.importESModule(
);
let FormAutofillStorage;
let CREDIT_CARD_SCHEMA_VERSION;
add_setup(async () => {
({ FormAutofillStorage } = ChromeUtils.import(
"resource://autofill/FormAutofillStorage.jsm"
));
({ CREDIT_CARD_SCHEMA_VERSION } = ChromeUtils.import(
"resource://autofill/FormAutofillStorageBase.jsm"
));
});
const TEST_STORE_FILE_NAME = "test-credit-card.json";
@ -26,7 +30,6 @@ const TEST_CREDIT_CARD_1 = {
"cc-number": "4929001587121045",
"cc-exp-month": 4,
"cc-exp-year": 2017,
"cc-type": "visa",
};
const TEST_CREDIT_CARD_2 = {
@ -34,20 +37,17 @@ const TEST_CREDIT_CARD_2 = {
"cc-number": "5103059495477870",
"cc-exp-month": 12,
"cc-exp-year": 2022,
"cc-type": "mastercard",
};
const TEST_CREDIT_CARD_3 = {
"cc-number": "3589993783099582",
"cc-exp-month": 1,
"cc-exp-year": 2000,
"cc-type": "amex",
};
const TEST_CREDIT_CARD_4 = {
"cc-name": "Foo Bar",
"cc-number": "3589993783099582",
"cc-type": "amex",
};
const TEST_CREDIT_CARD_WITH_BILLING_ADDRESS = {
@ -61,7 +61,6 @@ const TEST_CREDIT_CARD_WITH_EMPTY_FIELD = {
"cc-name": "",
"cc-number": "344060747836806",
"cc-exp-month": 1,
"cc-type": "",
};
const TEST_CREDIT_CARD_WITH_EMPTY_COMPUTED_FIELD = {
@ -96,14 +95,6 @@ const TEST_CREDIT_CARD_WITH_SPACES_BETWEEN_DIGITS = {
"cc-number": "5103 0594 9547 7870",
};
const TEST_CREDIT_CARD_WITH_INVALID_NETWORK = {
"cc-name": "John Doe",
"cc-number": "4929001587121045",
"cc-exp-month": 4,
"cc-exp-year": 2017,
"cc-type": "asiv",
};
const TEST_CREDIT_CARD_EMPTY_AFTER_NORMALIZE = {
"cc-exp-month": 13,
};
@ -332,7 +323,7 @@ add_task(async function test_add() {
do_check_credit_card_matches(creditCards[1], TEST_CREDIT_CARD_2);
Assert.notEqual(creditCards[0].guid, undefined);
Assert.equal(creditCards[0].version, 3);
Assert.equal(creditCards[0].version, CREDIT_CARD_SCHEMA_VERSION);
Assert.notEqual(creditCards[0].timeCreated, undefined);
Assert.equal(creditCards[0].timeLastModified, creditCards[0].timeCreated);
Assert.equal(creditCards[0].timeLastUsed, 0);
@ -543,8 +534,6 @@ add_task(async function test_validate() {
await profileStorage.creditCards.add(
TEST_CREDIT_CARD_WITH_SPACES_BETWEEN_DIGITS
);
await profileStorage.creditCards.add(TEST_CREDIT_CARD_WITH_INVALID_NETWORK);
let creditCards = await profileStorage.creditCards.getAll();
Assert.equal(creditCards[0]["cc-exp-month"], undefined);
@ -562,10 +551,6 @@ add_task(async function test_validate() {
);
Assert.equal(creditCards[2]["cc-number"].length, 16);
// dont enforce validity on the card network when storing a record,
// to avoid data loss when syncing records between different clients with different rules
Assert.equal(creditCards[3]["cc-type"], "asiv");
});
add_task(async function test_notifyUsed() {

View file

@ -13,8 +13,12 @@ add_setup(async () => {
const TEST_STORE_FILE_NAME = "test-profile.json";
const ADDRESS_SCHEMA_VERSION = 1;
const CREDIT_CARD_SCHEMA_VERSION = 3;
const { ADDRESS_SCHEMA_VERSION } = ChromeUtils.import(
"resource://autofill/FormAutofillStorageBase.jsm"
);
const { CREDIT_CARD_SCHEMA_VERSION } = ChromeUtils.import(
"resource://autofill/FormAutofillStorageBase.jsm"
);
const ADDRESS_TESTCASES = [
{

View file

@ -789,6 +789,10 @@ TESTCASES.forEach(testcase => {
.creditCard) {
delete ccRecord.flowId;
}
for (let addrRecord of FormAutofillContent._onFormSubmit.args[0][0]
.address) {
delete addrRecord.flowId;
}
Assert.deepEqual(
FormAutofillContent._onFormSubmit.args[0][0],

View file

@ -1,7 +1,9 @@
"use strict";
const TEST_STORE_FILE_NAME = "test-profile.json";
const CURRENT_CC_VERSION = 3;
const { CREDIT_CARD_SCHEMA_VERSION } = ChromeUtils.import(
"resource://autofill/FormAutofillStorageBase.jsm"
);
// NOTE: a guide to reading these test-cases:
// parent: What the local record looked like the last time we wrote the
@ -502,7 +504,7 @@ const CREDIT_CARD_RECONCILE_TESTCASES = [
parent: {
// So when we last wrote the record to the server, it had these values.
guid: "2bbd2d8fbc6b",
version: CURRENT_CC_VERSION,
version: CREDIT_CARD_SCHEMA_VERSION,
"cc-name": "John Doe",
"cc-number": "4111111111111111",
},
@ -519,7 +521,7 @@ const CREDIT_CARD_RECONCILE_TESTCASES = [
// we can deduce the record hasn't actually been changed remotely so we
// can safely ignore the incoming record and write our local changes.
guid: "2bbd2d8fbc6b",
version: CURRENT_CC_VERSION,
version: CREDIT_CARD_SCHEMA_VERSION,
"cc-name": "John Doe",
"cc-number": "4111111111111111",
},
@ -533,7 +535,7 @@ const CREDIT_CARD_RECONCILE_TESTCASES = [
description: "Remote change",
parent: {
guid: "e3680e9f890d",
version: CURRENT_CC_VERSION,
version: CREDIT_CARD_SCHEMA_VERSION,
"cc-name": "John Doe",
"cc-number": "4111111111111111",
},
@ -545,7 +547,7 @@ const CREDIT_CARD_RECONCILE_TESTCASES = [
],
remote: {
guid: "e3680e9f890d",
version: CURRENT_CC_VERSION,
version: CREDIT_CARD_SCHEMA_VERSION,
"cc-name": "John Doe",
"cc-number": "4929001587121045",
},
@ -560,7 +562,7 @@ const CREDIT_CARD_RECONCILE_TESTCASES = [
description: "New local field",
parent: {
guid: "0cba738b1be0",
version: CURRENT_CC_VERSION,
version: CREDIT_CARD_SCHEMA_VERSION,
"cc-name": "John Doe",
"cc-number": "4111111111111111",
},
@ -573,7 +575,7 @@ const CREDIT_CARD_RECONCILE_TESTCASES = [
],
remote: {
guid: "0cba738b1be0",
version: CURRENT_CC_VERSION,
version: CREDIT_CARD_SCHEMA_VERSION,
"cc-name": "John Doe",
"cc-number": "4111111111111111",
},
@ -588,7 +590,7 @@ const CREDIT_CARD_RECONCILE_TESTCASES = [
description: "New remote field",
parent: {
guid: "be3ef97f8285",
version: CURRENT_CC_VERSION,
version: CREDIT_CARD_SCHEMA_VERSION,
"cc-name": "John Doe",
"cc-number": "4111111111111111",
},
@ -600,7 +602,7 @@ const CREDIT_CARD_RECONCILE_TESTCASES = [
],
remote: {
guid: "be3ef97f8285",
version: CURRENT_CC_VERSION,
version: CREDIT_CARD_SCHEMA_VERSION,
"cc-name": "John Doe",
"cc-number": "4111111111111111",
"cc-exp-month": 12,
@ -616,7 +618,7 @@ const CREDIT_CARD_RECONCILE_TESTCASES = [
description: "Deleted field locally",
parent: {
guid: "9627322248ec",
version: CURRENT_CC_VERSION,
version: CREDIT_CARD_SCHEMA_VERSION,
"cc-name": "John Doe",
"cc-number": "4111111111111111",
"cc-exp-month": 12,
@ -629,7 +631,7 @@ const CREDIT_CARD_RECONCILE_TESTCASES = [
],
remote: {
guid: "9627322248ec",
version: CURRENT_CC_VERSION,
version: CREDIT_CARD_SCHEMA_VERSION,
"cc-name": "John Doe",
"cc-number": "4111111111111111",
"cc-exp-month": 12,
@ -644,7 +646,7 @@ const CREDIT_CARD_RECONCILE_TESTCASES = [
description: "Deleted field remotely",
parent: {
guid: "7d7509f3eeb2",
version: CURRENT_CC_VERSION,
version: CREDIT_CARD_SCHEMA_VERSION,
"cc-name": "John Doe",
"cc-number": "4111111111111111",
"cc-exp-month": 12,
@ -658,7 +660,7 @@ const CREDIT_CARD_RECONCILE_TESTCASES = [
],
remote: {
guid: "7d7509f3eeb2",
version: CURRENT_CC_VERSION,
version: CREDIT_CARD_SCHEMA_VERSION,
"cc-name": "John Doe",
"cc-number": "4111111111111111",
},
@ -673,7 +675,7 @@ const CREDIT_CARD_RECONCILE_TESTCASES = [
parent: {
// The last time we wrote this to the server, "cc-exp-month" was 12.
guid: "e087a06dfc57",
version: CURRENT_CC_VERSION,
version: CREDIT_CARD_SCHEMA_VERSION,
"cc-name": "John Doe",
"cc-number": "4111111111111111",
"cc-exp-month": 12,
@ -689,7 +691,7 @@ const CREDIT_CARD_RECONCILE_TESTCASES = [
remote: {
// Remotely, we've changed "cc-exp-month" to 1.
guid: "e087a06dfc57",
version: CURRENT_CC_VERSION,
version: CREDIT_CARD_SCHEMA_VERSION,
"cc-name": "John Doe",
"cc-number": "4111111111111111",
"cc-exp-month": 1,
@ -705,7 +707,7 @@ const CREDIT_CARD_RECONCILE_TESTCASES = [
description: "Multiple local changes",
parent: {
guid: "340a078c596f",
version: CURRENT_CC_VERSION,
version: CREDIT_CARD_SCHEMA_VERSION,
"cc-name": "John Doe",
"cc-number": "4111111111111111",
},
@ -722,7 +724,7 @@ const CREDIT_CARD_RECONCILE_TESTCASES = [
],
remote: {
guid: "340a078c596f",
version: CURRENT_CC_VERSION,
version: CREDIT_CARD_SCHEMA_VERSION,
"cc-name": "John Doe",
"cc-number": "4111111111111111",
"cc-exp-year": 2000,
@ -741,7 +743,7 @@ const CREDIT_CARD_RECONCILE_TESTCASES = [
description: "Same change to local and remote",
parent: {
guid: "0b3a72a1bea2",
version: CURRENT_CC_VERSION,
version: CREDIT_CARD_SCHEMA_VERSION,
"cc-name": "John Doe",
"cc-number": "4111111111111111",
},
@ -753,7 +755,7 @@ const CREDIT_CARD_RECONCILE_TESTCASES = [
],
remote: {
guid: "0b3a72a1bea2",
version: CURRENT_CC_VERSION,
version: CREDIT_CARD_SCHEMA_VERSION,
"cc-name": "John Doe",
"cc-number": "4929001587121045",
},
@ -768,7 +770,7 @@ const CREDIT_CARD_RECONCILE_TESTCASES = [
parent: {
// This is what we last wrote to the sync server.
guid: "62068784d089",
version: CURRENT_CC_VERSION,
version: CREDIT_CARD_SCHEMA_VERSION,
"cc-name": "John Doe",
"cc-number": "4111111111111111",
},
@ -782,7 +784,7 @@ const CREDIT_CARD_RECONCILE_TESTCASES = [
remote: {
// An incoming record has a different cc-number than any of the above!
guid: "62068784d089",
version: CURRENT_CC_VERSION,
version: CREDIT_CARD_SCHEMA_VERSION,
"cc-name": "John Doe",
"cc-number": "4929001587121045",
},
@ -803,7 +805,7 @@ const CREDIT_CARD_RECONCILE_TESTCASES = [
description: "Conflicting changes to multiple fields",
parent: {
guid: "244dbb692e94",
version: CURRENT_CC_VERSION,
version: CREDIT_CARD_SCHEMA_VERSION,
"cc-name": "John Doe",
"cc-number": "4111111111111111",
"cc-exp-month": 12,
@ -817,7 +819,7 @@ const CREDIT_CARD_RECONCILE_TESTCASES = [
],
remote: {
guid: "244dbb692e94",
version: CURRENT_CC_VERSION,
version: CREDIT_CARD_SCHEMA_VERSION,
"cc-name": "John Doe",
"cc-number": "4929001587121045",
"cc-exp-month": 3,
@ -838,7 +840,7 @@ const CREDIT_CARD_RECONCILE_TESTCASES = [
description: "Field deleted locally, changed remotely",
parent: {
guid: "6fc45e03d19a",
version: CURRENT_CC_VERSION,
version: CREDIT_CARD_SCHEMA_VERSION,
"cc-name": "John Doe",
"cc-number": "4111111111111111",
"cc-exp-month": 12,
@ -851,7 +853,7 @@ const CREDIT_CARD_RECONCILE_TESTCASES = [
],
remote: {
guid: "6fc45e03d19a",
version: CURRENT_CC_VERSION,
version: CREDIT_CARD_SCHEMA_VERSION,
"cc-name": "John Doe",
"cc-number": "4111111111111111",
"cc-exp-month": 3,
@ -871,7 +873,7 @@ const CREDIT_CARD_RECONCILE_TESTCASES = [
description: "Field changed locally, deleted remotely",
parent: {
guid: "fff9fa27fa18",
version: CURRENT_CC_VERSION,
version: CREDIT_CARD_SCHEMA_VERSION,
"cc-name": "John Doe",
"cc-number": "4111111111111111",
"cc-exp-month": 12,
@ -885,7 +887,7 @@ const CREDIT_CARD_RECONCILE_TESTCASES = [
],
remote: {
guid: "fff9fa27fa18",
version: CURRENT_CC_VERSION,
version: CREDIT_CARD_SCHEMA_VERSION,
"cc-name": "John Doe",
"cc-number": "4111111111111111",
},
@ -908,7 +910,7 @@ const CREDIT_CARD_RECONCILE_TESTCASES = [
"Created, last modified time reconciliation without local changes",
parent: {
guid: "5113f329c42f",
version: CURRENT_CC_VERSION,
version: CREDIT_CARD_SCHEMA_VERSION,
"cc-name": "John Doe",
"cc-number": "4111111111111111",
timeCreated: 1234,
@ -919,7 +921,7 @@ const CREDIT_CARD_RECONCILE_TESTCASES = [
local: [],
remote: {
guid: "5113f329c42f",
version: CURRENT_CC_VERSION,
version: CREDIT_CARD_SCHEMA_VERSION,
"cc-name": "John Doe",
"cc-number": "4111111111111111",
timeCreated: 1200,
@ -944,7 +946,7 @@ const CREDIT_CARD_RECONCILE_TESTCASES = [
"Created, last modified time reconciliation with local changes",
parent: {
guid: "791e5608b80a",
version: CURRENT_CC_VERSION,
version: CREDIT_CARD_SCHEMA_VERSION,
"cc-name": "John Doe",
"cc-number": "4111111111111111",
timeCreated: 1234,
@ -960,7 +962,7 @@ const CREDIT_CARD_RECONCILE_TESTCASES = [
],
remote: {
guid: "791e5608b80a",
version: CURRENT_CC_VERSION,
version: CREDIT_CARD_SCHEMA_VERSION,
"cc-name": "John Doe",
"cc-number": "4111111111111111",
timeCreated: 1300,

View file

@ -88,6 +88,7 @@ scn
sco
si
sk
skr
sl
son
sq

View file

@ -123,7 +123,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "e73dd755139b3d985731378b10b5ad24a1f5ca25"
"revision": "0f0d3136fa24c1901f6dd9b6dd10ec4417b7fab7"
},
"bg": {
"pin": false,
@ -339,7 +339,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "85cbb5ac2b413fbdcbae9cfc53ee34af3e84e0f2"
"revision": "d8143d7bea232f589629de51d40827f29e5cff96"
},
"da": {
"pin": false,
@ -411,7 +411,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "6b53abe8b72ea7d750dbf784579cebe0ac1371f8"
"revision": "cc1dc18e3264abc89a4c0f131bba483127e3b171"
},
"en-CA": {
"pin": false,
@ -537,7 +537,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "36348ed52001471790c80a418c95b0810f5cba80"
"revision": "fad4d0adf55e0d539e8d5638a9229dccf329b637"
},
"et": {
"pin": false,
@ -645,7 +645,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "e3f9e8ff98337a83ed0979cac4532db38faa15c7"
"revision": "7fd2fbb98c207008a3235eb6f2e113e6ed9a04fb"
},
"fur": {
"pin": false,
@ -753,7 +753,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "7821f81585331a9b1848d1d5d642dd73f38ae91c"
"revision": "f3e74c5c1482f033effc224f176add1a16a3c9ba"
},
"gu-IN": {
"pin": false,
@ -951,7 +951,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "cc2b619be1ce02242ce61772ad81398444b70695"
"revision": "81b996adfd75830caa46b821fced3aef131f91a7"
},
"it": {
"pin": false,
@ -969,7 +969,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "4abcaafa38b73ce43950e9af9068e67f7e81f4cf"
"revision": "1d5629288311618b21c2f6f415fbb5d69807815c"
},
"ja": {
"pin": false,
@ -985,7 +985,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "ed389a9b49500d50ad446d5c9dfe6332897820d1"
"revision": "cfddf1c79a8f8cd1d398a17e9d9817e3520127eb"
},
"ja-JP-mac": {
"pin": false,
@ -993,7 +993,7 @@
"macosx64",
"macosx64-devedition"
],
"revision": "b090f5309b9050f055ecfd08e4f793b1fa2584de"
"revision": "ac842d8c1ffa8d135791b37632ec517ad2193136"
},
"ka": {
"pin": false,
@ -1011,7 +1011,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "3fa202c59e7c9af2f59343f36e9619776f0bcc07"
"revision": "85b331506ec3ce225b8089eaae25d2f40e7dc1c6"
},
"kab": {
"pin": false,
@ -1137,7 +1137,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "f31e152b1c8f6e40465c11d28137ab28f05a177e"
"revision": "b243016d49f81fa9cee263cd14f309478414c7b9"
},
"lt": {
"pin": false,
@ -1299,7 +1299,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "2792b6c6afa8441df2cf5484c955d6ae0d4708b0"
"revision": "641aa975e46f49a6e9c47e99feccab2c1b765627"
},
"ne-NP": {
"pin": false,
@ -1353,7 +1353,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "9c856743327b84db315cbde108d9b6fccb055c5e"
"revision": "4e9d67e248082b59f63dc84c97d83e5031073a0d"
},
"oc": {
"pin": false,
@ -1371,7 +1371,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "5e8a6032d35706a72d38f10596511ed6f21f57c2"
"revision": "835b4db39af6a5b1465b6bcc9e0fea5428d582b9"
},
"pa-IN": {
"pin": false,
@ -1425,7 +1425,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "ee6b31ef07ee183b086095f8ef6e5270e9a1edb9"
"revision": "ba6d673558bc64ae2b011fc0883f2e3342404369"
},
"pt-PT": {
"pin": false,
@ -1443,7 +1443,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "0a94cc0c13042d3a6058d0646d4909f87eea6a22"
"revision": "25a53a92a5eb074080f955ee45e0421ba42e2cb1"
},
"rm": {
"pin": false,
@ -1497,7 +1497,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "a0ae1d6c4c23d591be97fb749d590bda8c28099f"
"revision": "58d56e44e4c81c1b66341b46d0683e04678dcfe5"
},
"sat": {
"pin": false,
@ -1607,6 +1607,24 @@
],
"revision": "c395c8165c9f849280b981c393925e0c86eefdd7"
},
"skr": {
"pin": false,
"platforms": [
"linux",
"linux-devedition",
"linux64",
"linux64-devedition",
"macosx64",
"macosx64-devedition",
"win32",
"win32-devedition",
"win64",
"win64-aarch64",
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "90f661a930e68528569bc06ce4b7c9c954a91841"
},
"sl": {
"pin": false,
"platforms": [
@ -1767,7 +1785,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "6c3379096389f70507715a74cd974ad916efb7bb"
"revision": "81e5d1a66d0cd69220eb6c9a2ef089aba810efc2"
},
"th": {
"pin": false,
@ -1821,7 +1839,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "ca39fced5560da8842c5ff3097b9f68e92be4444"
"revision": "fbbfc98674781991d886bb09167c75e2b0ac2ff7"
},
"trs": {
"pin": false,
@ -1857,7 +1875,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "7f86fa3c0a197465ecc9e429f831838232bf4609"
"revision": "571f0043f3f3de6bb12a5fde277b6794db9f07a0"
},
"ur": {
"pin": false,

View file

@ -95,6 +95,7 @@ locales = [
"sco",
"si",
"sk",
"skr",
"sl",
"son",
"sq",

View file

@ -182,7 +182,7 @@ const AboutNewTab = {
this.activityStream.init();
this._subscribeToActivityStream();
} catch (e) {
Cu.reportError(e);
console.error(e);
}
},
@ -209,7 +209,7 @@ const AboutNewTab = {
try {
unsubscribe();
} catch (e) {
Cu.reportError(e);
console.error(e);
}
};
},

View file

@ -135,7 +135,7 @@ var BrowserUIUtils = {
}
let numberOfInsertionPoints = msg.match(/%\d+\$S/g).length;
if (numberOfInsertionPoints != nodesOrStrings.length) {
Cu.reportError(
console.error(
`Message has ${numberOfInsertionPoints} insertion points, ` +
`but got ${nodesOrStrings.length} replacement parameters!`
);

View file

@ -1158,7 +1158,7 @@ let BrowserUsageTelemetry = {
// time.
fileData = { version: "1", profileTelemetryIds: [] };
if (!(ex.name == "NotFoundError")) {
Cu.reportError(ex);
console.error(ex);
// Don't just return here on a read error. We need to send the error
// value to telemetry and we want to attempt to fix the file.
// However, we will still report an error for this ping, even if we
@ -1184,7 +1184,7 @@ let BrowserUsageTelemetry = {
JSON.stringify(fileData)
);
} catch (ex) {
Cu.reportError(ex);
console.error(ex);
writeError = true;
}
}

View file

@ -245,11 +245,11 @@ var TabCrashHandler = {
*/
onSelectedBrowserCrash(browser, restartRequired) {
if (!browser.isRemoteBrowser) {
Cu.reportError("Selected crashed browser is not remote.");
console.error("Selected crashed browser is not remote.");
return;
}
if (!browser.frameLoader) {
Cu.reportError("Selected crashed browser has no frameloader.");
console.error("Selected crashed browser has no frameloader.");
return;
}
@ -640,7 +640,7 @@ var TabCrashHandler = {
lazy.CrashSubmit.submit(dumpID, lazy.CrashSubmit.SUBMITTED_FROM_CRASH_TAB, {
recordSubmission: true,
extraExtraKeyVals,
}).catch(Cu.reportError);
}).catch(console.error);
this.prefs.setBoolPref("sendReport", true);
this.prefs.setBoolPref("includeURL", includeURL);
@ -718,7 +718,7 @@ var TabCrashHandler = {
onAboutTabCrashedUnload(browser) {
if (!this._crashedTabCount) {
Cu.reportError("Can not decrement crashed tab count to below 0");
console.error("Can not decrement crashed tab count to below 0");
return;
}
this._crashedTabCount--;
@ -897,7 +897,7 @@ var UnsubmittedCrashHandler = {
try {
reportIDs = await lazy.CrashSubmit.pendingIDs(dateLimit);
} catch (e) {
Cu.reportError(e);
console.error(e);
return null;
}
@ -1139,7 +1139,7 @@ var UnsubmittedCrashHandler = {
*/
submitReports(reportIDs, submittedFrom) {
for (let reportID of reportIDs) {
lazy.CrashSubmit.submit(reportID, submittedFrom).catch(Cu.reportError);
lazy.CrashSubmit.submit(reportID, submittedFrom).catch(console.error);
}
},
};

View file

@ -580,7 +580,7 @@ class IconLoader {
} catch (e) {
if (e.result != Cr.NS_BINDING_ABORTED) {
if (typeof e.data?.wrappedJSObject?.httpStatus !== "number") {
Cu.reportError(e);
console.error(e);
}
// Used mainly for tests currently.

View file

@ -197,7 +197,7 @@ let HomePage = {
await this.delayedStartup();
if (await this.shouldIgnore(value)) {
Cu.reportError(
console.error(
`Ignoring homepage setting for ${value} as it is on the ignore list.`
);
Services.telemetry.recordEvent(
@ -297,7 +297,7 @@ let HomePage = {
lazy.ExtensionPreferencesManager.removeSetting(
item.id,
"homepage_override"
).catch(Cu.reportError);
).catch(console.error);
} else {
// If we don't have a setting for it, we assume the pref has
// been incorrectly set somehow.

View file

@ -152,15 +152,15 @@ let LaterRun = {
let urlString = Services.urlFormatter.formatURL(pageData.url.trim());
uri = Services.io.newURI(urlString);
} catch (ex) {
Cu.reportError(
"Invalid LaterRun page URL " + pageData.url + " ignored."
console.error(
"Invalid LaterRun page URL ",
pageData.url,
" ignored."
);
continue;
}
if (!uri.schemeIs("https")) {
Cu.reportError(
"Insecure LaterRun page URL " + uri.spec + " ignored."
);
console.error("Insecure LaterRun page URL ", uri.spec, " ignored.");
} else {
pageData.url = uri.spec;
rv.push(new Page(pageData));

View file

@ -114,7 +114,7 @@ export var PartnerLinkAttribution = {
let searchUrlQueryParamName = engine.searchUrlQueryParamName;
if (!searchUrlQueryParamName) {
Cu.reportError("makeSearchEngineRequest can't find search terms key");
console.error("makeSearchEngineRequest can't find search terms key");
return;
}
@ -125,9 +125,7 @@ export var PartnerLinkAttribution = {
let targetParams = new URLSearchParams(url.query);
if (!targetParams.has(searchUrlQueryParamName)) {
Cu.reportError(
"makeSearchEngineRequest can't remove target search terms"
);
console.error("makeSearchEngineRequest can't remove target search terms");
return;
}
@ -164,7 +162,7 @@ export var PartnerLinkAttribution = {
*/
sendContextualServicesPing(payload, pingType) {
if (!Object.values(CONTEXTUAL_SERVICES_PING_TYPES).includes(pingType)) {
Cu.reportError("Invalid Contextual Services ping type");
console.error("Invalid Contextual Services ping type");
return;
}

View file

@ -126,7 +126,7 @@ class PingCentre {
return PingCentre._sendStandalonePing(endpoint, payload).catch(event => {
Glean.pingCentre.sendFailures.add(1);
Cu.reportError(
console.error(
`Structured Ingestion ping failure with error: ${event.type}`
);
});
@ -141,7 +141,7 @@ class PingCentre {
this._onFhrPrefChange
);
} catch (e) {
Cu.reportError(e);
console.error(e);
}
}
}

View file

@ -374,7 +374,7 @@ var ProcessHangMonitor = {
uri_type = "content";
}
} catch (ex) {
Cu.reportError(ex);
console.error(ex);
uri_type = "unknown";
}
}
@ -406,7 +406,7 @@ var ProcessHangMonitor = {
}
);
} catch (ex) {
Cu.reportError(ex);
console.error(ex);
}
},

View file

@ -183,11 +183,10 @@ export var Sanitizer = {
options.progress = { clearHonoringExceptions: true };
await this.sanitize(itemsToClear, options);
} catch (ex) {
Cu.reportError(
"A previously pending sanitization failed: " +
itemsToClear +
"\n" +
ex
console.error(
"A previously pending sanitization failed: ",
itemsToClear,
ex
);
}
}
@ -1147,7 +1146,7 @@ function safeGetPendingSanitizations() {
Services.prefs.getStringPref(Sanitizer.PREF_PENDING_SANITIZATIONS, "[]")
);
} catch (ex) {
Cu.reportError("Invalid JSON value for pending sanitizations: " + ex);
console.error("Invalid JSON value for pending sanitizations: ", ex);
return [];
}
}

View file

@ -196,7 +196,7 @@ var SiteDataManager = {
principal.originAttributes.partitionKey
);
} catch (e) {
Cu.reportError(e);
console.error(e);
}
let site = this._getOrInsertSite(
pkBaseDomain || principal.baseDomain
@ -254,7 +254,7 @@ var SiteDataManager = {
cookie.originAttributes.partitionKey
);
} catch (e) {
Cu.reportError(e);
console.error(e);
}
let baseDomainOrHost =
pkBaseDomain || this.getBaseDomainFromHost(cookie.rawHost);

View file

@ -423,8 +423,11 @@ var Builder = class {
}
},
handleError(aError) {
Cu.reportError(
"Async execution error (" + aError.result + "): " + aError.message
console.error(
"Async execution error (",
aError.result,
"): ",
aError.message
);
},
handleCompletion(aReason) {
@ -446,7 +449,7 @@ var Builder = class {
.filter(uri => !!uri);
if (URIsToRemove.length) {
lazy.PlacesUtils.history.remove(URIsToRemove).catch(Cu.reportError);
lazy.PlacesUtils.history.remove(URIsToRemove).catch(console.error);
}
}
};

View file

@ -233,7 +233,7 @@ PreviewController.prototype = {
{
fullScale: aFullScale,
}
).catch(e => Cu.reportError(e));
).catch(console.error);
// If we're updating the canvas, then we're in the middle of a peek so
// don't discard the cache of previews.
},

View file

@ -73,7 +73,7 @@ var ZoomUI = {
resolve(value);
},
handleError(error) {
Cu.reportError(error);
console.error(error);
},
});
});

Some files were not shown because too many files have changed in this diff Show more