From 26a029d407be480d791972afb5975cf62c9360a6 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 02:47:55 +0200 Subject: Adding upstream version 124.0.1. Signed-off-by: Daniel Baumann --- .../test/browser/abouthomecache/browser.toml | 52 + .../abouthomecache/browser_basic_endtoend.js | 22 + .../browser/abouthomecache/browser_bump_version.js | 35 + .../browser/abouthomecache/browser_disabled.js | 97 + .../browser_experiments_api_control.js | 63 + .../abouthomecache/browser_locale_change.js | 30 + .../browser/abouthomecache/browser_no_cache.js | 27 + .../browser_no_cache_on_SessionStartup_restore.js | 37 + .../abouthomecache/browser_no_startup_actions.js | 83 + .../abouthomecache/browser_overwrite_cache.js | 38 + .../abouthomecache/browser_process_crash.js | 82 + .../abouthomecache/browser_same_consumer.js | 52 + .../browser/abouthomecache/browser_sanitize.js | 54 + .../abouthomecache/browser_shutdown_timeout.js | 45 + .../newtab/test/browser/abouthomecache/head.js | 365 ++ .../newtab/test/browser/annotation_first.html | 2 + .../newtab/test/browser/annotation_second.html | 2 + .../newtab/test/browser/annotation_third.html | 2 + .../components/newtab/test/browser/blue_page.html | 6 + .../components/newtab/test/browser/browser.toml | 81 + .../test/browser/browser_as_load_location.js | 44 + .../newtab/test/browser/browser_as_render.js | 83 + .../test/browser/browser_context_menu_item.js | 18 + .../test/browser/browser_customize_menu_content.js | 219 ++ .../test/browser/browser_customize_menu_render.js | 28 + .../newtab/test/browser/browser_discovery_card.js | 49 + .../test/browser/browser_discovery_render.js | 31 + .../test/browser/browser_enabled_newtabpage.js | 33 + .../test/browser/browser_foxdoodle_set_default.js | 69 + .../newtab/test/browser/browser_getScreenshots.js | 88 + .../test/browser/browser_highlights_section.js | 96 + .../test/browser/browser_multistage_spotlight.js | 90 + .../browser_multistage_spotlight_telemetry.js | 141 + .../newtab/test/browser/browser_newtab_glean.js | 28 + .../newtab/test/browser/browser_newtab_header.js | 76 + .../test/browser/browser_newtab_last_LinkMenu.js | 153 + .../test/browser/browser_newtab_overrides.js | 134 + .../newtab/test/browser/browser_newtab_ping.js | 216 ++ .../newtab/test/browser/browser_newtab_towindow.js | 45 + .../newtab/test/browser/browser_newtab_trigger.js | 50 + .../newtab/test/browser/browser_open_tab_focus.js | 38 + .../newtab/test/browser/browser_remote_l10n.js | 56 + .../test/browser/browser_topsites_annotation.js | 980 ++++++ .../browser_topsites_contextMenu_options.js | 126 + .../test/browser/browser_topsites_section.js | 304 ++ .../test/browser/browser_trigger_messagesLoaded.js | 153 + .../components/newtab/test/browser/file_pdf.PDF | 12 + browser/components/newtab/test/browser/head.js | 244 ++ .../components/newtab/test/browser/red_page.html | 6 + .../components/newtab/test/browser/redirect_to.sjs | 9 + .../components/newtab/test/browser/topstories.json | 11 + .../test/schemas/asrouter_event_ping.schema.json | 36 + .../newtab/test/schemas/base_ping.schema.json | 29 + browser/components/newtab/test/schemas/pings.js | 181 + .../newtab/test/schemas/session_ping.schema.json | 122 + .../test/schemas/user_event_ping.schema.json | 75 + .../newtab/test/unit/common/Actions.test.js | 236 ++ .../newtab/test/unit/common/Dedupe.test.js | 38 + .../newtab/test/unit/common/Reducers.test.js | 1525 +++++++++ .../test/unit/content-src/components/Base.test.jsx | 130 + .../test/unit/content-src/components/Card.test.jsx | 510 +++ .../components/CollapsibleSection.test.jsx | 67 + .../components/ComponentPerfTimer.test.jsx | 447 +++ .../content-src/components/ConfirmDialog.test.jsx | 182 + .../content-src/components/ContextMenu.test.jsx | 227 ++ .../content-src/components/CustomiseMenu.test.jsx | 72 + .../components/DiscoveryStreamAdmin.test.jsx | 267 ++ .../components/DiscoveryStreamBase.test.jsx | 313 ++ .../DiscoveryStreamComponents/CardGrid.test.jsx | 354 ++ .../CollectionCardGrid.test.jsx | 138 + .../DiscoveryStreamComponents/DSCard.test.jsx | 582 ++++ .../DSContextFooter.test.jsx | 138 + .../DiscoveryStreamComponents/DSDismiss.test.jsx | 51 + .../DSEmptyState.test.jsx | 73 + .../DiscoveryStreamComponents/DSImage.test.jsx | 146 + .../DiscoveryStreamComponents/DSLinkMenu.test.jsx | 151 + .../DiscoveryStreamComponents/DSMessage.test.jsx | 57 + .../DSPrivacyModal.test.jsx | 50 + .../DiscoveryStreamComponents/DSSignup.test.jsx | 92 + .../DiscoveryStreamComponents/DSTextPromo.test.jsx | 96 + .../DiscoveryStreamComponents/Highlights.test.jsx | 41 + .../HorizontalRule.test.jsx | 16 + .../ImpressionStats.test.jsx | 276 ++ .../DiscoveryStreamComponents/Navigation.test.jsx | 131 + .../DiscoveryStreamComponents/PrivacyLink.test.jsx | 29 + .../DiscoveryStreamComponents/SafeAnchor.test.jsx | 56 + .../SectionTitle.test.jsx | 22 + .../TopicsWidget.test.jsx | 238 ++ .../content-src/components/ErrorBoundary.test.jsx | 110 + .../content-src/components/FluentOrText.test.jsx | 68 + .../unit/content-src/components/LinkMenu.test.jsx | 667 ++++ .../components/MoreRecommendations.test.jsx | 24 + .../components/PocketLoggedInCta.test.jsx | 46 + .../unit/content-src/components/Search.test.jsx | 179 + .../unit/content-src/components/Sections.test.jsx | 600 ++++ .../unit/content-src/components/TopSites.test.jsx | 1930 +++++++++++ .../TopSites/SearchShortcutsForm.test.jsx | 56 + .../TopSites/TopSiteImpressionWrapper.test.jsx | 148 + .../unit/content-src/components/Topics.test.jsx | 22 + .../lib/detect-user-session-start.test.js | 120 + .../test/unit/content-src/lib/init-store.test.js | 155 + .../test/unit/content-src/lib/perf-service.test.js | 89 + .../unit/content-src/lib/screenshot-utils.test.js | 147 + .../content-src/lib/selectLayoutRender.test.js | 576 ++++ .../newtab/test/unit/lib/AboutPreferences.test.js | 429 +++ .../newtab/test/unit/lib/ActivityStream.test.js | 576 ++++ .../unit/lib/ActivityStreamMessageChannel.test.js | 445 +++ .../test/unit/lib/ActivityStreamPrefs.test.js | 113 + .../test/unit/lib/ActivityStreamStorage.test.js | 161 + .../test/unit/lib/DiscoveryStreamFeed.test.js | 3523 ++++++++++++++++++++ .../newtab/test/unit/lib/DownloadsManager.test.js | 373 +++ .../newtab/test/unit/lib/FaviconFeed.test.js | 233 ++ .../newtab/test/unit/lib/FilterAdult.test.js | 112 + .../newtab/test/unit/lib/LinksCache.test.js | 16 + .../newtab/test/unit/lib/NewTabInit.test.js | 81 + .../newtab/test/unit/lib/PersistentCache.test.js | 142 + .../NaiveBayesTextTagger.test.js | 95 + .../lib/PersonalityProvider/NmfTextTagger.test.js | 479 +++ .../PersonalityProvider.test.js | 356 ++ .../PersonalityProviderWorkerClass.test.js | 456 +++ .../lib/PersonalityProvider/RecipeExecutor.test.js | 1543 +++++++++ .../unit/lib/PersonalityProvider/Tokenize.test.js | 134 + .../newtab/test/unit/lib/PrefsFeed.test.js | 357 ++ .../test/unit/lib/RecommendationProvider.test.js | 331 ++ .../newtab/test/unit/lib/Screenshots.test.js | 209 ++ .../newtab/test/unit/lib/SectionsManager.test.js | 897 +++++ .../newtab/test/unit/lib/ShortUrl.test.js | 104 + .../newtab/test/unit/lib/SiteClassifier.test.js | 252 ++ .../newtab/test/unit/lib/SystemTickFeed.test.js | 79 + .../newtab/test/unit/lib/TippyTopProvider.test.js | 121 + .../newtab/test/unit/lib/UTEventReporting.test.js | 115 + browser/components/newtab/test/unit/unit-entry.js | 733 ++++ browser/components/newtab/test/unit/utils.js | 406 +++ .../xpcshell/test_AboutHomeStartupCacheChild.js | 33 + .../xpcshell/test_AboutHomeStartupCacheWorker.js | 255 ++ .../newtab/test/xpcshell/test_AboutNewTab.js | 363 ++ .../test/xpcshell/test_AboutWelcomeAttribution.js | 69 + .../test/xpcshell/test_AboutWelcomeTelemetry.js | 90 + .../xpcshell/test_AboutWelcomeTelemetry_glean.js | 238 ++ .../newtab/test/xpcshell/test_HighlightsFeed.js | 1402 ++++++++ .../newtab/test/xpcshell/test_PlacesFeed.js | 1812 ++++++++++ .../components/newtab/test/xpcshell/test_Store.js | 453 +++ .../newtab/test/xpcshell/test_TelemetryFeed.js | 3285 ++++++++++++++++++ .../newtab/test/xpcshell/test_TopSitesFeed.js | 3397 +++++++++++++++++++ .../test/xpcshell/test_TopSitesFeed_glean.js | 2023 +++++++++++ .../newtab/test/xpcshell/topstories.json | 53 + .../components/newtab/test/xpcshell/xpcshell.toml | 34 + 147 files changed, 43314 insertions(+) create mode 100644 browser/components/newtab/test/browser/abouthomecache/browser.toml create mode 100644 browser/components/newtab/test/browser/abouthomecache/browser_basic_endtoend.js create mode 100644 browser/components/newtab/test/browser/abouthomecache/browser_bump_version.js create mode 100644 browser/components/newtab/test/browser/abouthomecache/browser_disabled.js create mode 100644 browser/components/newtab/test/browser/abouthomecache/browser_experiments_api_control.js create mode 100644 browser/components/newtab/test/browser/abouthomecache/browser_locale_change.js create mode 100644 browser/components/newtab/test/browser/abouthomecache/browser_no_cache.js create mode 100644 browser/components/newtab/test/browser/abouthomecache/browser_no_cache_on_SessionStartup_restore.js create mode 100644 browser/components/newtab/test/browser/abouthomecache/browser_no_startup_actions.js create mode 100644 browser/components/newtab/test/browser/abouthomecache/browser_overwrite_cache.js create mode 100644 browser/components/newtab/test/browser/abouthomecache/browser_process_crash.js create mode 100644 browser/components/newtab/test/browser/abouthomecache/browser_same_consumer.js create mode 100644 browser/components/newtab/test/browser/abouthomecache/browser_sanitize.js create mode 100644 browser/components/newtab/test/browser/abouthomecache/browser_shutdown_timeout.js create mode 100644 browser/components/newtab/test/browser/abouthomecache/head.js create mode 100644 browser/components/newtab/test/browser/annotation_first.html create mode 100644 browser/components/newtab/test/browser/annotation_second.html create mode 100644 browser/components/newtab/test/browser/annotation_third.html create mode 100644 browser/components/newtab/test/browser/blue_page.html create mode 100644 browser/components/newtab/test/browser/browser.toml create mode 100644 browser/components/newtab/test/browser/browser_as_load_location.js create mode 100644 browser/components/newtab/test/browser/browser_as_render.js create mode 100644 browser/components/newtab/test/browser/browser_context_menu_item.js create mode 100644 browser/components/newtab/test/browser/browser_customize_menu_content.js create mode 100644 browser/components/newtab/test/browser/browser_customize_menu_render.js create mode 100644 browser/components/newtab/test/browser/browser_discovery_card.js create mode 100644 browser/components/newtab/test/browser/browser_discovery_render.js create mode 100644 browser/components/newtab/test/browser/browser_enabled_newtabpage.js create mode 100644 browser/components/newtab/test/browser/browser_foxdoodle_set_default.js create mode 100644 browser/components/newtab/test/browser/browser_getScreenshots.js create mode 100644 browser/components/newtab/test/browser/browser_highlights_section.js create mode 100644 browser/components/newtab/test/browser/browser_multistage_spotlight.js create mode 100644 browser/components/newtab/test/browser/browser_multistage_spotlight_telemetry.js create mode 100644 browser/components/newtab/test/browser/browser_newtab_glean.js create mode 100644 browser/components/newtab/test/browser/browser_newtab_header.js create mode 100644 browser/components/newtab/test/browser/browser_newtab_last_LinkMenu.js create mode 100644 browser/components/newtab/test/browser/browser_newtab_overrides.js create mode 100644 browser/components/newtab/test/browser/browser_newtab_ping.js create mode 100644 browser/components/newtab/test/browser/browser_newtab_towindow.js create mode 100644 browser/components/newtab/test/browser/browser_newtab_trigger.js create mode 100644 browser/components/newtab/test/browser/browser_open_tab_focus.js create mode 100644 browser/components/newtab/test/browser/browser_remote_l10n.js create mode 100644 browser/components/newtab/test/browser/browser_topsites_annotation.js create mode 100644 browser/components/newtab/test/browser/browser_topsites_contextMenu_options.js create mode 100644 browser/components/newtab/test/browser/browser_topsites_section.js create mode 100644 browser/components/newtab/test/browser/browser_trigger_messagesLoaded.js create mode 100644 browser/components/newtab/test/browser/file_pdf.PDF create mode 100644 browser/components/newtab/test/browser/head.js create mode 100644 browser/components/newtab/test/browser/red_page.html create mode 100644 browser/components/newtab/test/browser/redirect_to.sjs create mode 100644 browser/components/newtab/test/browser/topstories.json create mode 100644 browser/components/newtab/test/schemas/asrouter_event_ping.schema.json create mode 100644 browser/components/newtab/test/schemas/base_ping.schema.json create mode 100644 browser/components/newtab/test/schemas/pings.js create mode 100644 browser/components/newtab/test/schemas/session_ping.schema.json create mode 100644 browser/components/newtab/test/schemas/user_event_ping.schema.json create mode 100644 browser/components/newtab/test/unit/common/Actions.test.js create mode 100644 browser/components/newtab/test/unit/common/Dedupe.test.js create mode 100644 browser/components/newtab/test/unit/common/Reducers.test.js create mode 100644 browser/components/newtab/test/unit/content-src/components/Base.test.jsx create mode 100644 browser/components/newtab/test/unit/content-src/components/Card.test.jsx create mode 100644 browser/components/newtab/test/unit/content-src/components/CollapsibleSection.test.jsx create mode 100644 browser/components/newtab/test/unit/content-src/components/ComponentPerfTimer.test.jsx create mode 100644 browser/components/newtab/test/unit/content-src/components/ConfirmDialog.test.jsx create mode 100644 browser/components/newtab/test/unit/content-src/components/ContextMenu.test.jsx create mode 100644 browser/components/newtab/test/unit/content-src/components/CustomiseMenu.test.jsx create mode 100644 browser/components/newtab/test/unit/content-src/components/DiscoveryStreamAdmin.test.jsx create mode 100644 browser/components/newtab/test/unit/content-src/components/DiscoveryStreamBase.test.jsx create mode 100644 browser/components/newtab/test/unit/content-src/components/DiscoveryStreamComponents/CardGrid.test.jsx create mode 100644 browser/components/newtab/test/unit/content-src/components/DiscoveryStreamComponents/CollectionCardGrid.test.jsx create mode 100644 browser/components/newtab/test/unit/content-src/components/DiscoveryStreamComponents/DSCard.test.jsx create mode 100644 browser/components/newtab/test/unit/content-src/components/DiscoveryStreamComponents/DSContextFooter.test.jsx create mode 100644 browser/components/newtab/test/unit/content-src/components/DiscoveryStreamComponents/DSDismiss.test.jsx create mode 100644 browser/components/newtab/test/unit/content-src/components/DiscoveryStreamComponents/DSEmptyState.test.jsx create mode 100644 browser/components/newtab/test/unit/content-src/components/DiscoveryStreamComponents/DSImage.test.jsx create mode 100644 browser/components/newtab/test/unit/content-src/components/DiscoveryStreamComponents/DSLinkMenu.test.jsx create mode 100644 browser/components/newtab/test/unit/content-src/components/DiscoveryStreamComponents/DSMessage.test.jsx create mode 100644 browser/components/newtab/test/unit/content-src/components/DiscoveryStreamComponents/DSPrivacyModal.test.jsx create mode 100644 browser/components/newtab/test/unit/content-src/components/DiscoveryStreamComponents/DSSignup.test.jsx create mode 100644 browser/components/newtab/test/unit/content-src/components/DiscoveryStreamComponents/DSTextPromo.test.jsx create mode 100644 browser/components/newtab/test/unit/content-src/components/DiscoveryStreamComponents/Highlights.test.jsx create mode 100644 browser/components/newtab/test/unit/content-src/components/DiscoveryStreamComponents/HorizontalRule.test.jsx create mode 100644 browser/components/newtab/test/unit/content-src/components/DiscoveryStreamComponents/ImpressionStats.test.jsx create mode 100644 browser/components/newtab/test/unit/content-src/components/DiscoveryStreamComponents/Navigation.test.jsx create mode 100644 browser/components/newtab/test/unit/content-src/components/DiscoveryStreamComponents/PrivacyLink.test.jsx create mode 100644 browser/components/newtab/test/unit/content-src/components/DiscoveryStreamComponents/SafeAnchor.test.jsx create mode 100644 browser/components/newtab/test/unit/content-src/components/DiscoveryStreamComponents/SectionTitle.test.jsx create mode 100644 browser/components/newtab/test/unit/content-src/components/DiscoveryStreamComponents/TopicsWidget.test.jsx create mode 100644 browser/components/newtab/test/unit/content-src/components/ErrorBoundary.test.jsx create mode 100644 browser/components/newtab/test/unit/content-src/components/FluentOrText.test.jsx create mode 100644 browser/components/newtab/test/unit/content-src/components/LinkMenu.test.jsx create mode 100644 browser/components/newtab/test/unit/content-src/components/MoreRecommendations.test.jsx create mode 100644 browser/components/newtab/test/unit/content-src/components/PocketLoggedInCta.test.jsx create mode 100644 browser/components/newtab/test/unit/content-src/components/Search.test.jsx create mode 100644 browser/components/newtab/test/unit/content-src/components/Sections.test.jsx create mode 100644 browser/components/newtab/test/unit/content-src/components/TopSites.test.jsx create mode 100644 browser/components/newtab/test/unit/content-src/components/TopSites/SearchShortcutsForm.test.jsx create mode 100644 browser/components/newtab/test/unit/content-src/components/TopSites/TopSiteImpressionWrapper.test.jsx create mode 100644 browser/components/newtab/test/unit/content-src/components/Topics.test.jsx create mode 100644 browser/components/newtab/test/unit/content-src/lib/detect-user-session-start.test.js create mode 100644 browser/components/newtab/test/unit/content-src/lib/init-store.test.js create mode 100644 browser/components/newtab/test/unit/content-src/lib/perf-service.test.js create mode 100644 browser/components/newtab/test/unit/content-src/lib/screenshot-utils.test.js create mode 100644 browser/components/newtab/test/unit/content-src/lib/selectLayoutRender.test.js create mode 100644 browser/components/newtab/test/unit/lib/AboutPreferences.test.js create mode 100644 browser/components/newtab/test/unit/lib/ActivityStream.test.js create mode 100644 browser/components/newtab/test/unit/lib/ActivityStreamMessageChannel.test.js create mode 100644 browser/components/newtab/test/unit/lib/ActivityStreamPrefs.test.js create mode 100644 browser/components/newtab/test/unit/lib/ActivityStreamStorage.test.js create mode 100644 browser/components/newtab/test/unit/lib/DiscoveryStreamFeed.test.js create mode 100644 browser/components/newtab/test/unit/lib/DownloadsManager.test.js create mode 100644 browser/components/newtab/test/unit/lib/FaviconFeed.test.js create mode 100644 browser/components/newtab/test/unit/lib/FilterAdult.test.js create mode 100644 browser/components/newtab/test/unit/lib/LinksCache.test.js create mode 100644 browser/components/newtab/test/unit/lib/NewTabInit.test.js create mode 100644 browser/components/newtab/test/unit/lib/PersistentCache.test.js create mode 100644 browser/components/newtab/test/unit/lib/PersonalityProvider/NaiveBayesTextTagger.test.js create mode 100644 browser/components/newtab/test/unit/lib/PersonalityProvider/NmfTextTagger.test.js create mode 100644 browser/components/newtab/test/unit/lib/PersonalityProvider/PersonalityProvider.test.js create mode 100644 browser/components/newtab/test/unit/lib/PersonalityProvider/PersonalityProviderWorkerClass.test.js create mode 100644 browser/components/newtab/test/unit/lib/PersonalityProvider/RecipeExecutor.test.js create mode 100644 browser/components/newtab/test/unit/lib/PersonalityProvider/Tokenize.test.js create mode 100644 browser/components/newtab/test/unit/lib/PrefsFeed.test.js create mode 100644 browser/components/newtab/test/unit/lib/RecommendationProvider.test.js create mode 100644 browser/components/newtab/test/unit/lib/Screenshots.test.js create mode 100644 browser/components/newtab/test/unit/lib/SectionsManager.test.js create mode 100644 browser/components/newtab/test/unit/lib/ShortUrl.test.js create mode 100644 browser/components/newtab/test/unit/lib/SiteClassifier.test.js create mode 100644 browser/components/newtab/test/unit/lib/SystemTickFeed.test.js create mode 100644 browser/components/newtab/test/unit/lib/TippyTopProvider.test.js create mode 100644 browser/components/newtab/test/unit/lib/UTEventReporting.test.js create mode 100644 browser/components/newtab/test/unit/unit-entry.js create mode 100644 browser/components/newtab/test/unit/utils.js create mode 100644 browser/components/newtab/test/xpcshell/test_AboutHomeStartupCacheChild.js create mode 100644 browser/components/newtab/test/xpcshell/test_AboutHomeStartupCacheWorker.js create mode 100644 browser/components/newtab/test/xpcshell/test_AboutNewTab.js create mode 100644 browser/components/newtab/test/xpcshell/test_AboutWelcomeAttribution.js create mode 100644 browser/components/newtab/test/xpcshell/test_AboutWelcomeTelemetry.js create mode 100644 browser/components/newtab/test/xpcshell/test_AboutWelcomeTelemetry_glean.js create mode 100644 browser/components/newtab/test/xpcshell/test_HighlightsFeed.js create mode 100644 browser/components/newtab/test/xpcshell/test_PlacesFeed.js create mode 100644 browser/components/newtab/test/xpcshell/test_Store.js create mode 100644 browser/components/newtab/test/xpcshell/test_TelemetryFeed.js create mode 100644 browser/components/newtab/test/xpcshell/test_TopSitesFeed.js create mode 100644 browser/components/newtab/test/xpcshell/test_TopSitesFeed_glean.js create mode 100644 browser/components/newtab/test/xpcshell/topstories.json create mode 100644 browser/components/newtab/test/xpcshell/xpcshell.toml (limited to 'browser/components/newtab/test') diff --git a/browser/components/newtab/test/browser/abouthomecache/browser.toml b/browser/components/newtab/test/browser/abouthomecache/browser.toml new file mode 100644 index 0000000000..1994415d9a --- /dev/null +++ b/browser/components/newtab/test/browser/abouthomecache/browser.toml @@ -0,0 +1,52 @@ +[DEFAULT] +support-files = [ + "head.js", + "../topstories.json", +] +prefs = [ + "browser.tabs.remote.separatePrivilegedContentProcess=true", + "browser.startup.homepage.abouthome_cache.enabled=true", + "browser.startup.homepage.abouthome_cache.cache_on_shutdown=false", + "browser.startup.homepage.abouthome_cache.loglevel=All", + "browser.startup.homepage.abouthome_cache.testing=true", + "browser.startup.page=1", + "browser.newtabpage.activity-stream.discoverystream.endpoints=data:", + "browser.newtabpage.activity-stream.feeds.system.topstories=true", + "browser.newtabpage.activity-stream.feeds.section.topstories=true", + "browser.newtabpage.activity-stream.feeds.system.topstories=true", + "browser.newtabpage.activity-stream.feeds.section.topstories.options={\"provider_name\":\"\"}", + "browser.newtabpage.activity-stream.telemetry.structuredIngestion=false", + "browser.newtabpage.activity-stream.discoverystream.endpoints=https://example.com", + "dom.ipc.processPrelaunch.delayMs=0", + # Bug 1694957 is why we need dom.ipc.processPrelaunch.delayMs=0 +] + +["browser_basic_endtoend.js"] + +["browser_bump_version.js"] + +["browser_disabled.js"] + +["browser_experiments_api_control.js"] + +["browser_locale_change.js"] + +["browser_no_cache.js"] + +["browser_no_cache_on_SessionStartup_restore.js"] + +["browser_no_startup_actions.js"] + +["browser_overwrite_cache.js"] + +["browser_process_crash.js"] +skip-if = [ + "!crashreporter", + "os == 'mac' && fission", # Bug 1659427; medium frequency intermittent on osx: test timed out +] + +["browser_same_consumer.js"] + +["browser_sanitize.js"] + +["browser_shutdown_timeout.js"] diff --git a/browser/components/newtab/test/browser/abouthomecache/browser_basic_endtoend.js b/browser/components/newtab/test/browser/abouthomecache/browser_basic_endtoend.js new file mode 100644 index 0000000000..bd42dd4af9 --- /dev/null +++ b/browser/components/newtab/test/browser/abouthomecache/browser_basic_endtoend.js @@ -0,0 +1,22 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +/** + * Tests that the about:home cache gets written on shutdown, and read + * from in the subsequent startup. + */ +add_task(async function test_basic_behaviour() { + await withFullyLoadedAboutHome(async browser => { + // First, clear the cache to test the base case. + await clearCache(); + await simulateRestart(browser); + await ensureCachedAboutHome(browser); + + // Next, test that a subsequent restart also shows the cached + // about:home. + await simulateRestart(browser); + await ensureCachedAboutHome(browser); + }); +}); diff --git a/browser/components/newtab/test/browser/abouthomecache/browser_bump_version.js b/browser/components/newtab/test/browser/abouthomecache/browser_bump_version.js new file mode 100644 index 0000000000..726b9aa973 --- /dev/null +++ b/browser/components/newtab/test/browser/abouthomecache/browser_bump_version.js @@ -0,0 +1,35 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +/** + * Test that if the "version" metadata on the cache entry doesn't match + * the expectation that we ignore the cache and load the dynamic about:home + * document. + */ +add_task(async function test_bump_version() { + await withFullyLoadedAboutHome(async browser => { + // First, ensure that a pre-existing cache exists. + await simulateRestart(browser); + + let cacheEntry = await AboutHomeStartupCache.ensureCacheEntry(); + Assert.equal( + cacheEntry.getMetaDataElement("version"), + Services.appinfo.appBuildID, + "Cache entry should be versioned on the build ID" + ); + cacheEntry.setMetaDataElement("version", "somethingnew"); + // We don't need to shutdown write or ensure the cache wins the race, + // since we expect the cache to be blown away because the version number + // has been bumped. + await simulateRestart(browser, { + withAutoShutdownWrite: false, + ensureCacheWinsRace: false, + }); + await ensureDynamicAboutHome( + browser, + AboutHomeStartupCache.CACHE_RESULT_SCALARS.INVALIDATED + ); + }); +}); diff --git a/browser/components/newtab/test/browser/abouthomecache/browser_disabled.js b/browser/components/newtab/test/browser/abouthomecache/browser_disabled.js new file mode 100644 index 0000000000..faa79b219c --- /dev/null +++ b/browser/components/newtab/test/browser/abouthomecache/browser_disabled.js @@ -0,0 +1,97 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +/** + * This file tests scenarios where the cache is disabled due to user + * configuration. + */ + +registerCleanupFunction(async () => { + // When the test completes, make sure we cleanup with a populated cache, + // since this is the default starting state for these tests. + await withFullyLoadedAboutHome(async browser => { + await simulateRestart(browser); + }); +}); + +/** + * Tests the case where the cache is disabled via the pref. + */ +add_task(async function test_cache_disabled() { + await withFullyLoadedAboutHome(async browser => { + await SpecialPowers.pushPrefEnv({ + set: [["browser.startup.homepage.abouthome_cache.enabled", false]], + }); + + await simulateRestart(browser); + + await ensureDynamicAboutHome( + browser, + AboutHomeStartupCache.CACHE_RESULT_SCALARS.DISABLED + ); + + await SpecialPowers.popPrefEnv(); + }); +}); + +/** + * Tests the case where the cache is disabled because the home page is + * not set at about:home. + */ +add_task(async function test_cache_custom_homepage() { + await withFullyLoadedAboutHome(async browser => { + await HomePage.set("https://example.com"); + await simulateRestart(browser); + + await ensureDynamicAboutHome( + browser, + AboutHomeStartupCache.CACHE_RESULT_SCALARS.NOT_LOADING_ABOUTHOME + ); + + HomePage.reset(); + }); +}); + +/** + * Tests the case where the cache is disabled because the session is + * configured to automatically be restored. + */ +add_task(async function test_cache_restore_session() { + await withFullyLoadedAboutHome(async browser => { + await SpecialPowers.pushPrefEnv({ + set: [["browser.startup.page", 3]], + }); + + await simulateRestart(browser); + + await ensureDynamicAboutHome( + browser, + AboutHomeStartupCache.CACHE_RESULT_SCALARS.NOT_LOADING_ABOUTHOME + ); + + await SpecialPowers.popPrefEnv(); + }); +}); + +/** + * Tests the case where the cache is disabled because about:newtab + * preloading is disabled. + */ +add_task(async function test_cache_no_preloading() { + await withFullyLoadedAboutHome(async browser => { + await SpecialPowers.pushPrefEnv({ + set: [["browser.newtab.preload", false]], + }); + + await simulateRestart(browser); + + await ensureDynamicAboutHome( + browser, + AboutHomeStartupCache.CACHE_RESULT_SCALARS.PRELOADING_DISABLED + ); + + await SpecialPowers.popPrefEnv(); + }); +}); diff --git a/browser/components/newtab/test/browser/abouthomecache/browser_experiments_api_control.js b/browser/components/newtab/test/browser/abouthomecache/browser_experiments_api_control.js new file mode 100644 index 0000000000..a94f1fe055 --- /dev/null +++ b/browser/components/newtab/test/browser/abouthomecache/browser_experiments_api_control.js @@ -0,0 +1,63 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const { ExperimentFakes } = ChromeUtils.importESModule( + "resource://testing-common/NimbusTestUtils.sys.mjs" +); + +registerCleanupFunction(async () => { + // When the test completes, make sure we cleanup with a populated cache, + // since this is the default starting state for these tests. + await withFullyLoadedAboutHome(async browser => { + await simulateRestart(browser); + }); +}); + +/** + * Tests that the ExperimentsAPI mechanism can be used to remotely + * enable and disable the about:home startup cache. + */ +add_task(async function test_experiments_api_control() { + // First, the disabled case. + await withFullyLoadedAboutHome(async browser => { + let doEnrollmentCleanup = await ExperimentFakes.enrollWithFeatureConfig({ + featureId: "abouthomecache", + value: { enabled: false }, + }); + + Assert.ok( + !NimbusFeatures.abouthomecache.getVariable("enabled"), + "NimbusFeatures should tell us that the about:home startup cache " + + "is disabled" + ); + + await simulateRestart(browser); + + await ensureDynamicAboutHome( + browser, + AboutHomeStartupCache.CACHE_RESULT_SCALARS.DISABLED + ); + + await doEnrollmentCleanup(); + }); + + // Now the enabled case. + await withFullyLoadedAboutHome(async browser => { + let doEnrollmentCleanup = await ExperimentFakes.enrollWithFeatureConfig({ + featureId: "abouthomecache", + value: { enabled: true }, + }); + + Assert.ok( + NimbusFeatures.abouthomecache.getVariable("enabled"), + "NimbusFeatures should tell us that the about:home startup cache " + + "is enabled" + ); + + await simulateRestart(browser); + await ensureCachedAboutHome(browser); + await doEnrollmentCleanup(); + }); +}); diff --git a/browser/components/newtab/test/browser/abouthomecache/browser_locale_change.js b/browser/components/newtab/test/browser/abouthomecache/browser_locale_change.js new file mode 100644 index 0000000000..e9e3c619ec --- /dev/null +++ b/browser/components/newtab/test/browser/abouthomecache/browser_locale_change.js @@ -0,0 +1,30 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +/** + * Tests that the about:home startup cache is cleared if the app + * locale changes. + */ +add_task(async function test_locale_change() { + await withFullyLoadedAboutHome(async browser => { + await simulateRestart(browser); + await ensureCachedAboutHome(browser); + + Services.obs.notifyObservers(null, "intl:app-locales-changed"); + await AboutHomeStartupCache.ensureCacheEntry(); + + // We're testing that switching locales blows away the cache, so we + // bypass the automatic writing of the cache on shutdown, and we + // also don't need to wait for the cache to be available. + await simulateRestart(browser, { + withAutoShutdownWrite: false, + ensureCacheWinsRace: false, + }); + await ensureDynamicAboutHome( + browser, + AboutHomeStartupCache.CACHE_RESULT_SCALARS.DOES_NOT_EXIST + ); + }); +}); diff --git a/browser/components/newtab/test/browser/abouthomecache/browser_no_cache.js b/browser/components/newtab/test/browser/abouthomecache/browser_no_cache.js new file mode 100644 index 0000000000..fdb51f8712 --- /dev/null +++ b/browser/components/newtab/test/browser/abouthomecache/browser_no_cache.js @@ -0,0 +1,27 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +requestLongerTimeout(2); + +/** + * Test that if there's no cache written, that we load the dynamic + * about:home document on startup. + */ +add_task(async function test_no_cache() { + await withFullyLoadedAboutHome(async browser => { + await clearCache(); + // We're testing the no-cache case, so we bypass the automatic writing + // of the cache on shutdown, and we also don't need to wait for the + // cache to be available. + await simulateRestart(browser, { + withAutoShutdownWrite: false, + ensureCacheWinsRace: false, + }); + await ensureDynamicAboutHome( + browser, + AboutHomeStartupCache.CACHE_RESULT_SCALARS.DOES_NOT_EXIST + ); + }); +}); diff --git a/browser/components/newtab/test/browser/abouthomecache/browser_no_cache_on_SessionStartup_restore.js b/browser/components/newtab/test/browser/abouthomecache/browser_no_cache_on_SessionStartup_restore.js new file mode 100644 index 0000000000..a312b2b44f --- /dev/null +++ b/browser/components/newtab/test/browser/abouthomecache/browser_no_cache_on_SessionStartup_restore.js @@ -0,0 +1,37 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +/** + * Tests that if somehow about:newtab loads before about:home does, that we + * don't use the cache. This is because about:newtab doesn't use the cache, + * and so it'll inevitably be newer than what's in the about:home cache, + * which will put the about:home cache out of date the next time about:home + * eventually loads. + */ +add_task(async function test_no_cache_on_SessionStartup_restore() { + await withFullyLoadedAboutHome(async browser => { + await simulateRestart(browser, { skipAboutHomeLoad: true }); + + // We remove the preloaded browser to ensure that loading the next + // about:newtab occurs now, and not at preloading time. + NewTabPagePreloading.removePreloadedBrowser(window); + let tab = await BrowserTestUtils.openNewForegroundTab( + gBrowser, + "about:newtab" + ); + + let newWin = await BrowserTestUtils.openNewBrowserWindow(); + + // The cache is disqualified because about:newtab was loaded first. + // So now it's too late to use the cache. + await ensureDynamicAboutHome( + newWin.gBrowser.selectedBrowser, + AboutHomeStartupCache.CACHE_RESULT_SCALARS.LATE + ); + + await BrowserTestUtils.closeWindow(newWin); + await BrowserTestUtils.removeTab(tab); + }); +}); diff --git a/browser/components/newtab/test/browser/abouthomecache/browser_no_startup_actions.js b/browser/components/newtab/test/browser/abouthomecache/browser_no_startup_actions.js new file mode 100644 index 0000000000..255b4c9d21 --- /dev/null +++ b/browser/components/newtab/test/browser/abouthomecache/browser_no_startup_actions.js @@ -0,0 +1,83 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +/** + * Tests that upon initializing Activity Stream, the cached about:home + * document does not process any actions caused by that initialization. + * This is because the restored Redux state from the cache should be enough, + * and processing any of the initialization messages from Activity Stream + * could wipe out that state and cause flicker / unnecessary redraws. + */ +add_task(async function test_no_startup_actions() { + await withFullyLoadedAboutHome(async browser => { + // Make sure we have a cached document. We simulate a restart to ensure + // that we start with a cache... that we can then clear without a problem, + // before writing a new cache. This ensures that no matter what, we're in a + // state where we have a fresh cache, regardless of what's happened in earlier + // tests. + await simulateRestart(browser); + await clearCache(); + await simulateRestart(browser); + await ensureCachedAboutHome(browser); + + // Set up a listener to monitor for actions that get dispatched in the + // browser when we fire Activity Stream up again. + await SpecialPowers.spawn(browser, [], async () => { + let xrayWindow = ChromeUtils.waiveXrays(content); + xrayWindow.nonStartupActions = []; + xrayWindow.startupActions = []; + xrayWindow.RPMAddMessageListener("ActivityStream:MainToContent", msg => { + if (msg.data.meta.isStartup) { + xrayWindow.startupActions.push(msg.data); + } else { + xrayWindow.nonStartupActions.push(msg.data); + } + }); + }); + + // The following two statements seem to be enough to simulate Activity + // Stream starting up. + AboutNewTab.activityStream.uninit(); + AboutNewTab.onBrowserReady(); + + // Much of Activity Stream initializes asynchronously. This is the easiest way + // I could find to ensure that enough of the feeds had initialized to produce + // a meaningful cached document. + await TestUtils.waitForCondition(() => { + let feed = AboutNewTab.activityStream.store.feeds.get( + "feeds.discoverystreamfeed" + ); + return feed?.loaded; + }); + + // Wait an additional few seconds for any other actions to get displayed. + // eslint-disable-next-line mozilla/no-arbitrary-setTimeout + await new Promise(resolve => setTimeout(resolve, 2000)); + + let [startupActions, nonStartupActions] = await SpecialPowers.spawn( + browser, + [], + async () => { + let xrayWindow = ChromeUtils.waiveXrays(content); + return [xrayWindow.startupActions, xrayWindow.nonStartupActions]; + } + ); + + Assert.ok(!!startupActions.length, "Should have seen startup actions."); + info(`Saw ${startupActions.length} startup actions.`); + + Assert.equal( + nonStartupActions.length, + 0, + "Should be no non-startup actions." + ); + + if (nonStartupActions.length) { + for (let action of nonStartupActions) { + info(`Non-startup action: ${action.type}`); + } + } + }); +}); diff --git a/browser/components/newtab/test/browser/abouthomecache/browser_overwrite_cache.js b/browser/components/newtab/test/browser/abouthomecache/browser_overwrite_cache.js new file mode 100644 index 0000000000..22df98794f --- /dev/null +++ b/browser/components/newtab/test/browser/abouthomecache/browser_overwrite_cache.js @@ -0,0 +1,38 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +/** + * Tests that if a pre-existing about:home cache exists, that it can + * be overwritten with new information. + */ +add_task(async function test_overwrite_cache() { + await withFullyLoadedAboutHome(async browser => { + await simulateRestart(browser); + const TEST_ID = "test_overwrite_cache_h1"; + + // We need the CSP meta tag in about: pages, otherwise we hit assertions in + // debug builds. + await injectIntoCache( + ` + + + + + +

Something new

+
+ + + `, + "window.__FROM_STARTUP_CACHE__ = true;" + ); + await simulateRestart(browser, { withAutoShutdownWrite: false }); + + await SpecialPowers.spawn(browser, [TEST_ID], async testID => { + let target = content.document.getElementById(testID); + Assert.ok(target, "Found the target element"); + }); + }); +}); diff --git a/browser/components/newtab/test/browser/abouthomecache/browser_process_crash.js b/browser/components/newtab/test/browser/abouthomecache/browser_process_crash.js new file mode 100644 index 0000000000..d3bfa383c2 --- /dev/null +++ b/browser/components/newtab/test/browser/abouthomecache/browser_process_crash.js @@ -0,0 +1,82 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +/** + * Test that if the "privileged about content process" crashes, that it + * drops its internal reference to the "privileged about content process" + * process manager, and that a subsequent restart of that process type + * results in a dynamic document load. Also tests that crashing of + * any other content process type doesn't clear the process manager + * reference. + */ +add_task(async function test_process_crash() { + await withFullyLoadedAboutHome(async browser => { + await simulateRestart(browser); + let origProcManager = AboutHomeStartupCache._procManager; + + await BrowserTestUtils.crashFrame(browser); + Assert.notEqual( + origProcManager, + AboutHomeStartupCache._procManager, + "Should have dropped the reference to the crashed process" + ); + }); + + await withFullyLoadedAboutHome(async browser => { + // The cache should still be considered "valid and used", since it was + // used successfully before the crash. + await ensureDynamicAboutHome( + browser, + AboutHomeStartupCache.CACHE_RESULT_SCALARS.VALID_AND_USED + ); + + // Now simulate a restart to attach the AboutHomeStartupCache to + // the new privileged about content process. + await simulateRestart(browser); + }); + + let latestProcManager = AboutHomeStartupCache._procManager; + + // eslint-disable-next-line @microsoft/sdl/no-insecure-url + await BrowserTestUtils.withNewTab("http://example.com", async browser => { + await BrowserTestUtils.crashFrame(browser); + Assert.equal( + latestProcManager, + AboutHomeStartupCache._procManager, + "Should still have the reference to the privileged about process" + ); + }); +}); + +/** + * Tests that if the "privileged about content process" crashes while + * a cache request is still underway, that the cache request resolves with + * null input streams. + */ +add_task(async function test_process_crash_while_requesting_streams() { + await withFullyLoadedAboutHome(async browser => { + await simulateRestart(browser); + let cacheStreamsPromise = AboutHomeStartupCache.requestCache(); + await BrowserTestUtils.crashFrame(browser); + let cacheStreams = await cacheStreamsPromise; + + if (!cacheStreams.pageInputStream && !cacheStreams.scriptInputStream) { + Assert.ok(true, "Page and script input streams are null."); + } else { + // It's possible (but probably rare) the parent was able to receive the + // streams before the crash occurred. In that case, we'll make sure that + // we can still read the streams. + info("Received the streams. Checking that they're readable."); + Assert.ok( + cacheStreams.pageInputStream.available(), + "Bytes available for page stream" + ); + Assert.ok( + cacheStreams.scriptInputStream.available(), + "Bytes available for script stream" + ); + } + }); +}); diff --git a/browser/components/newtab/test/browser/abouthomecache/browser_same_consumer.js b/browser/components/newtab/test/browser/abouthomecache/browser_same_consumer.js new file mode 100644 index 0000000000..75f8875f26 --- /dev/null +++ b/browser/components/newtab/test/browser/abouthomecache/browser_same_consumer.js @@ -0,0 +1,52 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +/** + * Tests that if a page attempts to load the script stream without + * having also loaded the page stream, that it will fail and get + * the default non-cached script. + */ +add_task(async function test_same_consumer() { + await withFullyLoadedAboutHome(async browser => { + await simulateRestart(browser); + + // We need the CSP meta tag in about: pages, otherwise we hit assertions in + // debug builds. + // + // We inject a script that sets a __CACHE_CONSUMED__ property to true on + // the window element. We'll test to ensure that if we try to load the + // script cache from a different BrowsingContext that this property is + // not set. + await injectIntoCache( + ` + + + + + +

A fake about:home page

+
+ + `, + "window.__CACHE_CONSUMED__ = true;" + ); + await simulateRestart(browser, { withAutoShutdownWrite: false }); + + // Attempting to load the script from the cache should fail, and instead load + // the markup. + await BrowserTestUtils.withNewTab("about:home?jscache", async browser2 => { + await SpecialPowers.spawn(browser2, [], async () => { + Assert.ok( + !Cu.waiveXrays(content).__CACHE_CONSUMED__, + "Should not have found __CACHE_CONSUMED__ property" + ); + Assert.ok( + content.document.body.classList.contains("activity-stream"), + "Should have found activity-stream class on element" + ); + }); + }); + }); +}); diff --git a/browser/components/newtab/test/browser/abouthomecache/browser_sanitize.js b/browser/components/newtab/test/browser/abouthomecache/browser_sanitize.js new file mode 100644 index 0000000000..4dc7ba2c89 --- /dev/null +++ b/browser/components/newtab/test/browser/abouthomecache/browser_sanitize.js @@ -0,0 +1,54 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +/** + * Tests that when sanitizing places history, session store or downloads, that + * the about:home cache gets blown away. + */ + +add_task(async function test_sanitize() { + let testFlags = [ + ["downloads", Ci.nsIClearDataService.CLEAR_DOWNLOADS], + ["places history", Ci.nsIClearDataService.CLEAR_HISTORY], + ["session history", Ci.nsIClearDataService.CLEAR_SESSION_HISTORY], + ]; + + await withFullyLoadedAboutHome(async browser => { + for (let [type, flag] of testFlags) { + await simulateRestart(browser); + await ensureCachedAboutHome(browser); + + info( + "Testing that the about:home startup cache is cleared when " + + `clearing ${type}` + ); + + await new Promise((resolve, reject) => { + Services.clearData.deleteData(flag, { + onDataDeleted(resultFlags) { + if (!resultFlags) { + resolve(); + } else { + reject(new Error(`Failed with flags: ${resultFlags}`)); + } + }, + }); + }); + + // For the purposes of the test, we don't want the write-on-shutdown + // behaviour here (because we just want to test that the cache doesn't + // exist on startup if the history data was cleared). We also therefore + // don't need to ensure that the cache wins the race. + await simulateRestart(browser, { + withAutoShutdownWrite: false, + ensureCacheWinsRace: false, + }); + await ensureDynamicAboutHome( + browser, + AboutHomeStartupCache.CACHE_RESULT_SCALARS.DOES_NOT_EXIST + ); + } + }); +}); diff --git a/browser/components/newtab/test/browser/abouthomecache/browser_shutdown_timeout.js b/browser/components/newtab/test/browser/abouthomecache/browser_shutdown_timeout.js new file mode 100644 index 0000000000..b1600bfe00 --- /dev/null +++ b/browser/components/newtab/test/browser/abouthomecache/browser_shutdown_timeout.js @@ -0,0 +1,45 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +/** + * Tests that if there's a substantial delay in getting the cache + * streams from the privileged about content process for any reason + * during shutdown, that we timeout and let the AsyncShutdown proceed, + * rather than letting it block until AsyncShutdown causes a shutdown + * hang crash. + */ +add_task(async function test_shutdown_timeout() { + await withFullyLoadedAboutHome(async browser => { + // First, make sure the cache is populated so that later on, after + // the timeout, simulateRestart doesn't complain about not finding + // a pre-existing cache. This complaining only happens if this test + // is run in isolation. + await clearCache(); + await simulateRestart(browser); + + // Next, manually shutdown the AboutHomeStartupCacheChild so that + // it doesn't respond to requests to the cache streams. + await SpecialPowers.spawn(browser, [], async () => { + let { AboutHomeStartupCacheChild } = ChromeUtils.importESModule( + "resource:///modules/AboutNewTabService.sys.mjs" + ); + AboutHomeStartupCacheChild.uninit(); + }); + + // Then, manually dirty the cache state so that we attempt to write + // on shutdown. + AboutHomeStartupCache.onPreloadedNewTabMessage(); + + await simulateRestart(browser, { expectTimeout: true }); + + Assert.ok( + true, + "We reached here, which means shutdown didn't block forever." + ); + + // Clear the cache so that we're not in a half-persisted state. + await clearCache(); + }); +}); diff --git a/browser/components/newtab/test/browser/abouthomecache/head.js b/browser/components/newtab/test/browser/abouthomecache/head.js new file mode 100644 index 0000000000..5599b2bd10 --- /dev/null +++ b/browser/components/newtab/test/browser/abouthomecache/head.js @@ -0,0 +1,365 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +let { AboutHomeStartupCache } = ChromeUtils.importESModule( + "resource:///modules/BrowserGlue.sys.mjs" +); +const { sinon } = ChromeUtils.importESModule( + "resource://testing-common/Sinon.sys.mjs" +); +const { DiscoveryStreamFeed } = ChromeUtils.importESModule( + "resource://activity-stream/lib/DiscoveryStreamFeed.sys.mjs" +); + +// Some Activity Stream preferences are JSON encoded, and quite complex. +// Hard-coding them here or in browser.ini makes them brittle to change. +// Instead, we pull the default prefs structures and set the values that +// we need and write them to preferences here dynamically. We do this in +// its own scope to avoid polluting the global scope. +{ + const { PREFS_CONFIG } = ChromeUtils.importESModule( + "resource://activity-stream/lib/ActivityStream.sys.mjs" + ); + + let defaultDSConfig = JSON.parse( + PREFS_CONFIG.get("discoverystream.config").getValue({ + geo: "US", + locale: "en-US", + }) + ); + + // Configure Activity Stream to query for the layout JSON file that points + // at the local top stories feed. + Services.prefs.setCharPref( + "browser.newtabpage.activity-stream.discoverystream.config", + JSON.stringify(defaultDSConfig) + ); +} + +/** + * Utility function that loads about:home in the current window in a new tab, and waits + * for the Discovery Stream cards to finish loading before running the taskFn function. + * Once taskFn exits, the about:home tab will be closed. + * + * @param {function} taskFn + * A function that will be run after about:home has finished loading. This can be + * an async function. + * @return {Promise} + * @resolves {undefined} + */ +function withFullyLoadedAboutHome(taskFn) { + const sandbox = sinon.createSandbox(); + sandbox + .stub(DiscoveryStreamFeed.prototype, "generateFeedUrl") + .returns( + "https://example.com/browser/browser/components/newtab/test/browser/topstories.json" + ); + + return BrowserTestUtils.withNewTab("about:home", async browser => { + await SpecialPowers.spawn(browser, [], async () => { + await ContentTaskUtils.waitForCondition( + () => + content.document.querySelectorAll( + "[data-section-id='topstories'] .ds-card-link" + ).length, + "Waiting for Discovery Stream to be rendered." + ); + }); + + await taskFn(browser); + sandbox.restore(); + }); +} + +/** + * Shuts down the AboutHomeStartupCache components in the parent process + * and privileged about content process, and then restarts them, simulating + * the parent process having restarted. + * + * @param browser () + * A with about:home running in it. This will be reloaded + * after the restart simultion is complete, and that reload will attempt + * to read any about:home cache contents. + * @param options (object, optional) + * + * An object with the following properties: + * + * withAutoShutdownWrite (boolean, optional): + * Whether or not the shutdown part of the simulation should cause the + * shutdown handler to run, which normally causes the cache to be + * written. Setting this to false is handy if the cache has been + * specially prepared for the subsequent startup, and we don't want to + * overwrite it. This defaults to true. + * + * ensureCacheWinsRace (boolean, optional): + * Ensures that the privileged about content process will be able to + * read the bytes from the streams sent down from the HTTP cache. Use + * this to avoid the HTTP cache "losing the race" against reading the + * about:home document from the omni.ja. This defaults to true. + * + * expectTimeout (boolean, optional): + * If true, indicates that it's expected that AboutHomeStartupCache will + * timeout when shutting down. If false, such timeouts will result in + * test failures. Defaults to false. + * + * skipAboutHomeLoad (boolean, optional): + * If true, doesn't automatically load about:home after the simulated + * restart. Defaults to false. + * + * @returns Promise + * @resolves undefined + * Resolves once the restart simulation is complete, and the + * pointed at about:home finishes reloading. + */ +async function simulateRestart( + browser, + { + withAutoShutdownWrite = true, + ensureCacheWinsRace = true, + expectTimeout = false, + skipAboutHomeLoad = false, + } = {} +) { + info("Simulating restart of the browser"); + if (browser.remoteType !== E10SUtils.PRIVILEGEDABOUT_REMOTE_TYPE) { + throw new Error( + "prepareLoadFromCache should only be called on a browser " + + "loaded in the privileged about content process." + ); + } + + if (withAutoShutdownWrite && AboutHomeStartupCache.initted) { + info("Simulating shutdown write"); + let timedOut = !(await AboutHomeStartupCache.onShutdown(expectTimeout)); + if (timedOut && !expectTimeout) { + Assert.ok( + false, + "AboutHomeStartupCache shutdown unexpectedly timed out." + ); + } else if (!timedOut && expectTimeout) { + Assert.ok(false, "AboutHomeStartupCache shutdown failed to time out."); + } + info("Shutdown write done"); + } else { + info("Intentionally skipping shutdown write"); + } + + AboutHomeStartupCache.uninit(); + + info("Waiting for AboutHomeStartupCacheChild to uninit"); + await SpecialPowers.spawn(browser, [], async () => { + let { AboutHomeStartupCacheChild } = ChromeUtils.importESModule( + "resource:///modules/AboutNewTabService.sys.mjs" + ); + AboutHomeStartupCacheChild.uninit(); + }); + info("AboutHomeStartupCacheChild uninitted"); + + AboutHomeStartupCache.init(); + + if (AboutHomeStartupCache.initted) { + let processManager = browser.messageManager.processMessageManager; + let pp = browser.browsingContext.currentWindowGlobal.domProcess; + let { childID } = pp; + AboutHomeStartupCache.onContentProcessCreated(childID, processManager, pp); + + info("Waiting for AboutHomeStartupCache cache entry"); + await AboutHomeStartupCache.ensureCacheEntry(); + info("Got AboutHomeStartupCache cache entry"); + + if (ensureCacheWinsRace) { + info("Ensuring cache bytes are available"); + await SpecialPowers.spawn(browser, [], async () => { + let { AboutHomeStartupCacheChild } = ChromeUtils.importESModule( + "resource:///modules/AboutNewTabService.sys.mjs" + ); + let pageStream = AboutHomeStartupCacheChild._pageInputStream; + let scriptStream = AboutHomeStartupCacheChild._scriptInputStream; + await ContentTaskUtils.waitForCondition(() => { + return pageStream.available() && scriptStream.available(); + }); + }); + } + } + + if (!skipAboutHomeLoad) { + info("Waiting for about:home to load"); + let loaded = BrowserTestUtils.browserLoaded(browser, false, "about:home"); + BrowserTestUtils.startLoadingURIString(browser, "about:home"); + await loaded; + info("about:home loaded"); + } +} + +/** + * Writes a page string and a script string into the cache for + * the next about:home load. + * + * @param page (String) + * The HTML content to write into the cache. This cannot be the empty + * string. Note that this string should contain a node that has an + * id of "root", in order for the newtab scripts to attach correctly. + * Otherwise, an exception might get thrown which can cause shutdown + * leaks. + * @param script (String) + * The JS content to write into the cache that can be loaded via + * about:home?jscache. This cannot be the empty string. + * @returns Promise + * @resolves undefined + * When the page and script content has been successfully written. + */ +async function injectIntoCache(page, script) { + if (!page || !script) { + throw new Error("Cannot injectIntoCache with falsey values"); + } + + if (!page.includes(`id="root"`)) { + throw new Error("Page markup must include a root node."); + } + + await AboutHomeStartupCache.ensureCacheEntry(); + + let pageInputStream = Cc[ + "@mozilla.org/io/string-input-stream;1" + ].createInstance(Ci.nsIStringInputStream); + + pageInputStream.setUTF8Data(page); + + let scriptInputStream = Cc[ + "@mozilla.org/io/string-input-stream;1" + ].createInstance(Ci.nsIStringInputStream); + + scriptInputStream.setUTF8Data(script); + + await AboutHomeStartupCache.populateCache(pageInputStream, scriptInputStream); +} + +/** + * Clears out any pre-existing about:home cache. + * @returns Promise + * @resolves undefined + * Resolves when the cache is cleared. + */ +async function clearCache() { + info("Test is clearing the cache"); + AboutHomeStartupCache.clearCache(); + await AboutHomeStartupCache.ensureCacheEntry(); + info("Test has cleared the cache."); +} + +/** + * Checks that the browser.startup.abouthome_cache_result scalar was + * recorded at a particular value. + * + * @param cacheResultScalar (Number) + * One of the AboutHomeStartupCache.CACHE_RESULT_SCALARS values. + */ +function assertCacheResultScalar(cacheResultScalar) { + let parentScalars = Services.telemetry.getSnapshotForScalars("main").parent; + Assert.equal( + parentScalars["browser.startup.abouthome_cache_result"], + cacheResultScalar, + "Expected the right value set to browser.startup.abouthome_cache_result " + + "scalar." + ); +} + +/** + * Tests that the about:home document loaded in a passed was + * one from the cache. + * + * We test for this by looking for some tell-tale signs of the cached + * document: + * + * 1. The about:home?jscache