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

MozReview-Commit-ID: 8kEDXaQ0zqK

--HG--
extra : rebase_source : 3994b272dc185ea25d4257eb79e766d23bf6892e
This commit is contained in:
Fischer.json 2017-06-16 17:44:06 +08:00
Родитель c8aecb9619
Коммит 14773a27fc
5 изменённых файлов: 223 добавлений и 9 удалений

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

@ -7,6 +7,10 @@
add_task(async function() {
await pushPrefs(["accessibility.tabfocus", 7]);
// When the onboarding component is enabled, it would inject extra tour notification into
// the newtab page so there would be 2 more notification close button and action button
let onbardingEnabled = AppConstants.NIGHTLY_BUILD && Services.prefs.getBoolPref("browser.onboarding.enabled");
// Focus count in new tab page.
// 30 = 9 * 3 + 3 = 9 sites, each with link, pin and remove buttons; search
// bar; search button; and toggle button. Additionaly there may or may not be
@ -17,16 +21,22 @@ add_task(async function() {
await setLinks("0,1,2,3,4,5,6,7,8");
setPinnedLinks("");
await addNewTabPageTab();
let tab = await addNewTabPageTab();
if (onbardingEnabled) {
FOCUS_COUNT += 2;
await promiseTourNotificationOpened(tab.linkedBrowser);
}
gURLBar.focus();
// Count the focus with the enabled page.
countFocus(FOCUS_COUNT);
// Disable page and count the focus with the disabled page.
NewTabUtils.allPages.enabled = false;
countFocus(4);
let expectedCount = 4;
if (onbardingEnabled) {
expectedCount += 2;
}
countFocus(expectedCount);
NewTabUtils.allPages.enabled = true;
});
@ -42,7 +52,30 @@ function countFocus(aExpectedCount) {
focusCount++;
}
} while (document.activeElement != gURLBar.inputField);
ok(focusCount == aExpectedCount || focusCount == (aExpectedCount + 1),
"Validate focus count in the new tab page.");
}
/**
* Wait for the onboarding tour notification opens
*/
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
);
}

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

@ -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,54 @@ 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 };
});
}