Bug 1196104 - Heartbeat: Support prompts that target private windows. r=bgrins

--HG--
extra : commitid : FcZQWsy7nB3
extra : rebase_source : 3e22c2fa152ebec371b8ab21885d81f3f2b1c2aa
This commit is contained in:
Matthew Noorenberghe 2015-08-28 15:13:59 -07:00
Родитель 77ea49ac86
Коммит 1d22b9fa15
3 изменённых файлов: 140 добавлений и 23 удалений

Просмотреть файл

@ -12,6 +12,7 @@ Cu.import("resource://gre/modules/AppConstants.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Promise.jsm");
Cu.import("resource:///modules/RecentWindow.jsm");
Cu.import("resource://gre/modules/Task.jsm");
Cu.import("resource://gre/modules/TelemetryController.jsm");
@ -399,7 +400,6 @@ this.UITour = {
window = Services.wm.getMostRecentWindow("navigator:browser");
}
let tab = window.gBrowser.getTabForBrowser(browser);
let messageManager = browser.messageManager;
log.debug("onPageEvent:", aEvent.detail, aMessage);
@ -479,8 +479,17 @@ this.UITour = {
return false;
}
let heartbeatWindow = window;
if (data.privateWindowsOnly && !PrivateBrowsingUtils.isWindowPrivate(heartbeatWindow)) {
heartbeatWindow = RecentWindow.getMostRecentBrowserWindow({ private: true });
if (!heartbeatWindow) {
log.debug("showHeartbeat: No private window found");
return false;
}
}
// Finally show the Heartbeat UI.
this.showHeartbeat(window, data);
this.showHeartbeat(heartbeatWindow, data);
break;
}
@ -1136,6 +1145,8 @@ this.UITour = {
* @param {String} [aOptions.learnMoreURL=null]
* The learn more URL to open when clicking on the learn more link. No learn more
* will be shown if this is an invalid URL.
* @param {String} [aOptions.privateWindowsOnly=false]
* Whether the heartbeat UI should only be targeted at a private window (if one exists).
*/
showHeartbeat(aChromeWindow, aOptions) {
let nb = aChromeWindow.document.getElementById("high-priority-global-notificationbox");

Просмотреть файл

@ -6,13 +6,13 @@
let gTestTab;
let gContentAPI;
let gContentWindow;
let notificationBox = document.getElementById("high-priority-global-notificationbox");
function test() {
UITourTest();
}
function getHeartbeatNotification(aId) {
function getHeartbeatNotification(aId, aChromeWindow = window) {
let notificationBox = aChromeWindow.document.getElementById("high-priority-global-notificationbox");
// UITour.jsm prefixes the notification box ID with "heartbeat-" to prevent collisions.
return notificationBox.getNotificationWithValue("heartbeat-" + aId);
}
@ -57,10 +57,12 @@ function clickLearnMore(aId) {
*
* @param aId
* The id of the notification box to remove.
* @param [aChromeWindow=window]
* The chrome window the notification box is in.
*/
function cleanUpNotification(aId) {
let notification = notificationBox.getNotificationWithValue("heartbeat-" + aId);
notificationBox.removeNotification(notification);
function cleanUpNotification(aId, aChromeWindow = window) {
let notification = getHeartbeatNotification(aId, aChromeWindow);
notification.close();
}
let tests = [
@ -284,7 +286,7 @@ let tests = [
ok(Number.isFinite(aData.timestamp), "Timestamp must be a number.");
is(gBrowser.tabs.length, expectedTabCount, "Engagement URL should open in a new tab.");
gBrowser.removeCurrentTab();
done();
executeSoon(done);
break;
}
default: {
@ -342,21 +344,108 @@ let tests = [
"What is this?", dummyURL);
},
function test_invalidEngagementButtonLabel(done) {
taskify(function test_invalidEngagementButtonLabel(done) {
let engagementURL = "http://example.com";
let flowId = "ui-engagewithfirefox-" + Math.random();
Services.mm.addMessageListener("UITour:onPageEvent", function onPageEvent(aMessage) {
Services.mm.removeMessageListener("UITour:onPageEvent", onPageEvent);
SimpleTest.executeSoon(() => {
ok(!(UITour.tourBrowsersByWindow.get(window) &&
UITour.tourBrowsersByWindow.get(window).has(gBrowser.selectedBrowser)),
"Invalid engagementButtonLabel should prevent init");
});
done();
});
gContentAPI.showHeartbeat("Do you want to engage with us?", "Thank you!", flowId, engagementURL, null, null, {
engagementButtonLabel: 42,
});
},
let eventPromise = promisePageEvent();
gContentAPI.showHeartbeat("Do you want to engage with us?", "Thank you!", flowId, engagementURL,
null, null, {
engagementButtonLabel: 42,
});
yield eventPromise;
ok(!isTourBrowser(gBrowser.selectedBrowser),
"Invalid engagementButtonLabel should prevent init");
}),
taskify(function test_privateWindowsOnly_noneOpen(done) {
let engagementURL = "http://example.com";
let flowId = "ui-engagewithfirefox-" + Math.random();
let eventPromise = promisePageEvent();
gContentAPI.showHeartbeat("Do you want to engage with us?", "Thank you!", flowId, engagementURL,
null, null, {
engagementButtonLabel: "Yes!",
privateWindowsOnly: true,
});
yield eventPromise;
ok(!isTourBrowser(gBrowser.selectedBrowser),
"If there are no private windows opened, tour init should be prevented");
}),
taskify(function test_privateWindowsOnly_notMostRecent(done) {
let engagementURL = "http://example.com";
let flowId = "ui-engagewithfirefox-" + Math.random();
let privateWin = yield BrowserTestUtils.openNewBrowserWindow({ private: true });
let mostRecentWin = yield BrowserTestUtils.openNewBrowserWindow();
let eventPromise = promisePageEvent();
gContentAPI.showHeartbeat("Do you want to engage with us?", "Thank you!", flowId, engagementURL,
null, null, {
engagementButtonLabel: "Yes!",
privateWindowsOnly: true,
});
yield eventPromise;
is(getHeartbeatNotification(flowId, window), null,
"Heartbeat shouldn't appear in the default window");
is(!!getHeartbeatNotification(flowId, privateWin), true,
"Heartbeat should appear in the most recent private window");
is(getHeartbeatNotification(flowId, mostRecentWin), null,
"Heartbeat shouldn't appear in the most recent non-private window");
yield BrowserTestUtils.closeWindow(mostRecentWin);
yield BrowserTestUtils.closeWindow(privateWin);
}),
taskify(function test_privateWindowsOnly() {
let engagementURL = "http://example.com";
let learnMoreURL = "http://example.org/learnmore/";
let flowId = "ui-engagewithfirefox-" + Math.random();
let privateWin = yield BrowserTestUtils.openNewBrowserWindow({ private: true });
gContentAPI.showHeartbeat("Do you want to engage with us?", "Thank you!", flowId, engagementURL,
"Learn More", learnMoreURL, {
engagementButtonLabel: "Yes!",
privateWindowsOnly: true,
});
yield promisePageEvent();
ok(isTourBrowser(gBrowser.selectedBrowser), "UITour should have been init for the browser");
let notification = getHeartbeatNotification(flowId, privateWin);
is(notification.querySelectorAll(".star-x").length, 0, "No stars should be present");
info("Test the learn more link.");
let learnMoreLink = notification.querySelector(".text-link");
is(learnMoreLink.value, "Learn More", "Check learn more label");
let learnMoreTabPromise = BrowserTestUtils.waitForNewTab(privateWin.gBrowser, null);
learnMoreLink.click();
let learnMoreTab = yield learnMoreTabPromise;
is(learnMoreTab.linkedBrowser.currentURI.host, "example.org", "Check learn more site opened");
ok(PrivateBrowsingUtils.isBrowserPrivate(learnMoreTab.linkedBrowser), "Ensure the learn more tab is private");
yield BrowserTestUtils.removeTab(learnMoreTab);
info("Test the engagement button's new tab.");
let engagementButton = notification.querySelector(".notification-button");
is(engagementButton.label, "Yes!", "Check engagement button text");
let engagementTabPromise = BrowserTestUtils.waitForNewTab(privateWin.gBrowser, null);
engagementButton.doCommand();
let engagementTab = yield engagementTabPromise;
is(engagementTab.linkedBrowser.currentURI.host, "example.com", "Check enagement site opened");
ok(PrivateBrowsingUtils.isBrowserPrivate(engagementTab.linkedBrowser), "Ensure the engagement tab is private");
yield BrowserTestUtils.removeTab(engagementTab);
yield BrowserTestUtils.closeWindow(privateWin);
}),
];

Просмотреть файл

@ -41,11 +41,13 @@ function waitForCondition(condition, nextTest, errorMsg) {
*/
function taskify(fun) {
return (done) => {
// Output the inner function name otherwise no name will be output.
info("\t" + fun.name);
return Task.spawn(fun).then(done, (reason) => {
ok(false, reason);
done();
});
}
};
}
function is_hidden(element) {
@ -189,6 +191,21 @@ function is_element_hidden(element, msg) {
ok(is_hidden(element), msg);
}
function isTourBrowser(aBrowser) {
let chromeWindow = aBrowser.ownerDocument.defaultView;
return UITour.tourBrowsersByWindow.has(chromeWindow) &&
UITour.tourBrowsersByWindow.get(chromeWindow).has(aBrowser);
}
function promisePageEvent() {
return new Promise((resolve) => {
Services.mm.addMessageListener("UITour:onPageEvent", function onPageEvent(aMessage) {
Services.mm.removeMessageListener("UITour:onPageEvent", onPageEvent);
SimpleTest.executeSoon(resolve);
});
});
}
function loadUITourTestPage(callback, host = "https://example.org/") {
if (gTestTab)
gBrowser.removeTab(gTestTab);