зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
c8aecb9619
Коммит
14773a27fc
|
@ -7,6 +7,10 @@
|
||||||
add_task(async function() {
|
add_task(async function() {
|
||||||
await pushPrefs(["accessibility.tabfocus", 7]);
|
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.
|
// Focus count in new tab page.
|
||||||
// 30 = 9 * 3 + 3 = 9 sites, each with link, pin and remove buttons; search
|
// 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
|
// 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");
|
await setLinks("0,1,2,3,4,5,6,7,8");
|
||||||
setPinnedLinks("");
|
setPinnedLinks("");
|
||||||
|
|
||||||
await addNewTabPageTab();
|
let tab = await addNewTabPageTab();
|
||||||
|
if (onbardingEnabled) {
|
||||||
|
FOCUS_COUNT += 2;
|
||||||
|
await promiseTourNotificationOpened(tab.linkedBrowser);
|
||||||
|
}
|
||||||
gURLBar.focus();
|
gURLBar.focus();
|
||||||
|
|
||||||
// Count the focus with the enabled page.
|
// Count the focus with the enabled page.
|
||||||
countFocus(FOCUS_COUNT);
|
countFocus(FOCUS_COUNT);
|
||||||
|
|
||||||
// Disable page and count the focus with the disabled page.
|
// Disable page and count the focus with the disabled page.
|
||||||
NewTabUtils.allPages.enabled = false;
|
NewTabUtils.allPages.enabled = false;
|
||||||
|
|
||||||
countFocus(4);
|
let expectedCount = 4;
|
||||||
|
if (onbardingEnabled) {
|
||||||
|
expectedCount += 2;
|
||||||
|
}
|
||||||
|
countFocus(expectedCount);
|
||||||
|
|
||||||
NewTabUtils.allPages.enabled = true;
|
NewTabUtils.allPages.enabled = true;
|
||||||
});
|
});
|
||||||
|
@ -42,7 +52,30 @@ function countFocus(aExpectedCount) {
|
||||||
focusCount++;
|
focusCount++;
|
||||||
}
|
}
|
||||||
} while (document.activeElement != gURLBar.inputField);
|
} while (document.activeElement != gURLBar.inputField);
|
||||||
|
|
||||||
ok(focusCount == aExpectedCount || focusCount == (aExpectedCount + 1),
|
ok(focusCount == aExpectedCount || focusCount == (aExpectedCount + 1),
|
||||||
"Validate focus count in the new tab page.");
|
"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
|
head.js
|
||||||
|
|
||||||
[browser_onboarding_hide_tours.js]
|
[browser_onboarding_hide_tours.js]
|
||||||
|
[browser_onboarding_notification.js]
|
||||||
|
|
|
@ -3,9 +3,6 @@
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const ABOUT_HOME_URL = "about:home";
|
|
||||||
const ABOUT_NEWTAB_URL = "about:newtab";
|
|
||||||
|
|
||||||
function assertOnboardingDestroyed(browser) {
|
function assertOnboardingDestroyed(browser) {
|
||||||
return ContentTask.spawn(browser, {}, function() {
|
return ContentTask.spawn(browser, {}, function() {
|
||||||
let expectedRemovals = [
|
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.
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
* 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) {
|
function promiseOnboardingOverlayLoaded(browser) {
|
||||||
// The onboarding overlay is init inside window.requestIdleCallback, not immediately,
|
// The onboarding overlay is init inside window.requestIdleCallback, not immediately,
|
||||||
|
@ -57,3 +80,54 @@ function promisePrefUpdated(name, expectedValue) {
|
||||||
Preferences.observe(name, onUpdate);
|
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 };
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче