Bug 1357641 - Part 2: Add the browser_onboarding_notification.js test, r=mossop

MozReview-Commit-ID: 8kEDXaQ0zqK

--HG--
extra : rebase_source : b0b7a39789880b84045619b0d2a1a73ef2f189d6
This commit is contained in:
Fischer.json 2017-06-16 17:44:06 +08:00
Родитель efb9ebb0bb
Коммит b0b89bf334
4 изменённых файлов: 186 добавлений и 4 удалений

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

@ -3,3 +3,4 @@ support-files =
head.js
[browser_onboarding_hide_tours.js]
[browser_onboarding_notification.js]

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

@ -3,9 +3,6 @@
"use strict";
const ABOUT_HOME_URL = "about:home";
const ABOUT_NEWTAB_URL = "about:newtab";
function assertOnboardingDestroyed(browser) {
return ContentTask.spawn(browser, {}, function() {
let expectedRemovals = [

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

@ -0,0 +1,109 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
add_task(async function test_show_tour_notifications_in_order() {
resetOnboardingDefaultState();
await SpecialPowers.pushPrefEnv({set: [["browser.onboarding.enabled", true]]});
let tourIds = TOUR_IDs;
let tab = null;
let targetTourId = null;
let reloadPromise = null;
let expectedPrefUpdate = null;
for (let i = 0; i < tourIds.length; ++i) {
expectedPrefUpdate = promisePrefUpdated("browser.onboarding.notification.lastPrompted", tourIds[i]);
if (tab) {
reloadPromise = BrowserTestUtils.browserLoaded(tab.linkedBrowser);
tab.linkedBrowser.reload();
await reloadPromise;
} else {
tab = await BrowserTestUtils.openNewForegroundTab(gBrowser);
await BrowserTestUtils.loadURI(tab.linkedBrowser, ABOUT_NEWTAB_URL);
}
await promiseOnboardingOverlayLoaded(tab.linkedBrowser);
await promiseTourNotificationOpened(tab.linkedBrowser);
targetTourId = await getCurrentNotificationTargetTourId(tab.linkedBrowser);
is(targetTourId, tourIds[i], "Should show tour notifications in order");
await expectedPrefUpdate;
}
expectedPrefUpdate = promisePrefUpdated("browser.onboarding.notification.lastPrompted", tourIds[0]);
reloadPromise = BrowserTestUtils.browserLoaded(tab.linkedBrowser);
tab.linkedBrowser.reload();
await reloadPromise;
await promiseOnboardingOverlayLoaded(tab.linkedBrowser);
await promiseTourNotificationOpened(tab.linkedBrowser);
targetTourId = await getCurrentNotificationTargetTourId(tab.linkedBrowser);
is(targetTourId, tourIds[0], "Should loop back to the 1st tour notification after showing all notifications");
await expectedPrefUpdate;
await BrowserTestUtils.removeTab(tab);
});
add_task(async function test_open_target_tour_from_notification() {
resetOnboardingDefaultState();
await SpecialPowers.pushPrefEnv({set: [["browser.onboarding.enabled", true]]});
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser);
await BrowserTestUtils.loadURI(tab.linkedBrowser, ABOUT_NEWTAB_URL);
await promiseOnboardingOverlayLoaded(tab.linkedBrowser);
await promiseTourNotificationOpened(tab.linkedBrowser);
let targetTourId = await getCurrentNotificationTargetTourId(tab.linkedBrowser);
await BrowserTestUtils.synthesizeMouseAtCenter("#onboarding-notification-action-btn", {}, tab.linkedBrowser);
await promiseOnboardingOverlayOpened(tab.linkedBrowser);
let { activeNavItemId, activePageId } = await getCurrentActiveTour(tab.linkedBrowser);
is(targetTourId, activeNavItemId, "Should navigate to the target tour item.");
is(`${targetTourId}-page`, activePageId, "Should display the target tour page.");
await BrowserTestUtils.removeTab(tab);
});
add_task(async function test_not_show_notification_for_completed_tour() {
resetOnboardingDefaultState();
await SpecialPowers.pushPrefEnv({set: [["browser.onboarding.enabled", true]]});
let tourIds = TOUR_IDs;
// Make only the last tour uncompleted
let lastTourId = tourIds[tourIds.length - 1];
for (let id of tourIds) {
if (id != lastTourId) {
setTourCompletedState(id, true);
}
}
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser);
await BrowserTestUtils.loadURI(tab.linkedBrowser, ABOUT_NEWTAB_URL);
await promiseOnboardingOverlayLoaded(tab.linkedBrowser);
await promiseTourNotificationOpened(tab.linkedBrowser);
let targetTourId = await getCurrentNotificationTargetTourId(tab.linkedBrowser);
is(targetTourId, lastTourId, "Should not show notification for completed tour");
await BrowserTestUtils.removeTab(tab);
});
add_task(async function test_skip_notification_for_completed_tour() {
resetOnboardingDefaultState();
await SpecialPowers.pushPrefEnv({set: [["browser.onboarding.enabled", true]]});
let tourIds = TOUR_IDs;
// Make only 2nd tour completed
await setTourCompletedState(tourIds[1], true);
// Test show notification for the 1st tour
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser);
await BrowserTestUtils.loadURI(tab.linkedBrowser, ABOUT_NEWTAB_URL);
await promiseOnboardingOverlayLoaded(tab.linkedBrowser);
await promiseTourNotificationOpened(tab.linkedBrowser);
let targetTourId = await getCurrentNotificationTargetTourId(tab.linkedBrowser);
is(targetTourId, tourIds[0], "Should show notification for incompleted tour");
// Test skip the 2nd tour and show notification for the 3rd tour
let reloadPromise = BrowserTestUtils.browserLoaded(tab.linkedBrowser);
tab.linkedBrowser.reload();
await reloadPromise;
await promiseOnboardingOverlayLoaded(tab.linkedBrowser);
await promiseTourNotificationOpened(tab.linkedBrowser);
targetTourId = await getCurrentNotificationTargetTourId(tab.linkedBrowser);
is(targetTourId, tourIds[2], "Should skip notification for the completed 2nd tour");
await BrowserTestUtils.removeTab(tab);
});

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

@ -1,7 +1,30 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
Cu.import("resource://gre/modules/Preferences.jsm");
let { Preferences } = Cu.import("resource://gre/modules/Preferences.jsm", {});
const ABOUT_HOME_URL = "about:home";
const ABOUT_NEWTAB_URL = "about:newtab";
const TOUR_IDs = [
"onboarding-tour-private-browsing",
"onboarding-tour-addons",
"onboarding-tour-customize",
"onboarding-tour-search",
"onboarding-tour-default-browser",
];
function resetOnboardingDefaultState() {
// All the prefs should be reset to the default states
// and no need to revert back so we don't use `SpecialPowers.pushPrefEnv` here.
Preferences.set("browser.onboarding.hidden", false);
Preferences.set("browser.onboarding.notification.finished", false);
Preferences.set("browser.onboarding.notification.lastPrompted", "");
TOUR_IDs.forEach(id => Preferences.set(`browser.onboarding.tour.${id}.completed`, false));
}
function setTourCompletedState(tourId, state) {
Preferences.set(`browser.onboarding.tour.${tourId}.completed`, state);
}
function promiseOnboardingOverlayLoaded(browser) {
// The onboarding overlay is init inside window.requestIdleCallback, not immediately,
@ -57,3 +80,55 @@ function promisePrefUpdated(name, expectedValue) {
Preferences.observe(name, onUpdate);
});
}
function promiseTourNotificationOpened(browser) {
let condition = () => {
return ContentTask.spawn(browser, {}, function() {
return new Promise(resolve => {
let bar = content.document.querySelector("#onboarding-notification-bar");
if (bar && bar.classList.contains("onboarding-opened") && bar.dataset.cssTransition == "end") {
resolve(true);
return;
}
resolve(false);
});
})
};
return BrowserTestUtils.waitForCondition(
condition,
"Should open tour notification",
100,
30
);
}
function getCurrentNotificationTargetTourId(browser) {
return ContentTask.spawn(browser, {}, function() {
let bar = content.document.querySelector("#onboarding-notification-bar");
return bar ? bar.dataset.targetTourId : null;
});
}
function getCurrentActiveTour(browser) {
return ContentTask.spawn(browser, {}, function() {
let list = content.document.querySelector("#onboarding-tour-list");
let items = list.querySelectorAll(".onboarding-tour-item");
let activeNavItemId = null;
for (let item of items) {
if (item.classList.contains("onboarding-active")) {
activeNavItemId = item.id;
break;
}
}
let activePageId = null;
let pages = content.document.querySelectorAll(".onboarding-tour-page");
for (let page of pages) {
if (page.style.display != "none") {
activePageId = page.id;
break;
}
}
return { activeNavItemId, activePageId };
});
}