head.js 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. "use strict";
  2. ChromeUtils.defineModuleGetter(this, "PlacesTestUtils",
  3. "resource://testing-common/PlacesTestUtils.jsm");
  4. ChromeUtils.defineModuleGetter(this, "QueryCache",
  5. "resource://activity-stream/lib/ASRouterTargeting.jsm");
  6. function popPrefs() {
  7. return SpecialPowers.popPrefEnv();
  8. }
  9. function pushPrefs(...prefs) {
  10. return SpecialPowers.pushPrefEnv({set: prefs});
  11. }
  12. async function setDefaultTopSites() { // eslint-disable-line no-unused-vars
  13. // The pref for TopSites is empty by default.
  14. await pushPrefs(["browser.newtabpage.activity-stream.default.sites",
  15. "https://www.youtube.com/,https://www.facebook.com/,https://www.amazon.com/,https://www.reddit.com/,https://www.wikipedia.org/,https://twitter.com/"]);
  16. // Toggle the feed off and on as a workaround to read the new prefs.
  17. await pushPrefs(["browser.newtabpage.activity-stream.feeds.topsites", false]);
  18. await pushPrefs(["browser.newtabpage.activity-stream.feeds.topsites", true]);
  19. await pushPrefs(["browser.newtabpage.activity-stream.improvesearch.topSiteSearchShortcuts", true]);
  20. }
  21. async function clearHistoryAndBookmarks() { // eslint-disable-line no-unused-vars
  22. await PlacesUtils.bookmarks.eraseEverything();
  23. await PlacesUtils.history.clear();
  24. QueryCache.expireAll();
  25. }
  26. /**
  27. * Helper to wait for potentially preloaded browsers to "load" where a preloaded
  28. * page has already loaded and won't trigger "load", and a "load"ed page might
  29. * not necessarily have had all its javascript/render logic executed.
  30. */
  31. async function waitForPreloaded(browser) {
  32. let readyState = await ContentTask.spawn(browser, {}, () => content.document.readyState);
  33. if (readyState !== "complete") {
  34. await BrowserTestUtils.browserLoaded(browser);
  35. }
  36. }
  37. /**
  38. * Helper to force the HighlightsFeed to update.
  39. */
  40. function refreshHighlightsFeed() {
  41. // Toggling the pref will clear the feed cache and force a places query.
  42. Services.prefs.setBoolPref("browser.newtabpage.activity-stream.feeds.section.highlights", false);
  43. Services.prefs.setBoolPref("browser.newtabpage.activity-stream.feeds.section.highlights", true);
  44. }
  45. /**
  46. * Helper to populate the Highlights section with bookmark cards.
  47. * @param count Number of items to add.
  48. */
  49. async function addHighlightsBookmarks(count) { // eslint-disable-line no-unused-vars
  50. const bookmarks = new Array(count).fill(null).map((entry, i) => ({
  51. parentGuid: PlacesUtils.bookmarks.unfiledGuid,
  52. title: "foo",
  53. url: `https://mozilla${i}.com/nowNew`,
  54. }));
  55. for (let placeInfo of bookmarks) {
  56. await PlacesUtils.bookmarks.insert(placeInfo);
  57. // Bookmarks need at least one visit to show up as highlights.
  58. await PlacesTestUtils.addVisits(placeInfo.url);
  59. }
  60. // Force HighlightsFeed to make a request for the new items.
  61. refreshHighlightsFeed();
  62. }
  63. /**
  64. * Helper to add various helpers to the content process by injecting variables
  65. * and functions to the `content` global.
  66. */
  67. function addContentHelpers() {
  68. const {document} = content;
  69. Object.assign(content, {
  70. /**
  71. * Click the context menu button for an item and get its options list.
  72. *
  73. * @param selector {String} Selector to get an item (e.g., top site, card)
  74. * @return {Array} The nodes for the options.
  75. */
  76. openContextMenuAndGetOptions(selector) {
  77. const item = document.querySelector(selector);
  78. const contextButton = item.querySelector(".context-menu-button");
  79. contextButton.click();
  80. const contextMenu = item.querySelector(".context-menu");
  81. const contextMenuList = contextMenu.querySelector(".context-menu-list");
  82. return [...contextMenuList.getElementsByClassName("context-menu-item")];
  83. },
  84. });
  85. }
  86. /**
  87. * Helper to run Activity Stream about:newtab test tasks in content.
  88. *
  89. * @param testInfo {Function|Object}
  90. * {Function} This parameter will be used as if the function were called with
  91. * an Object with this parameter as "test" key's value.
  92. * {Object} The following keys are expected:
  93. * before {Function} Optional. Runs before and returns an arg for "test"
  94. * test {Function} The test to run in the about:newtab content task taking
  95. * an arg from "before" and returns a result to "after"
  96. * after {Function} Optional. Runs after and with the result of "test"
  97. */
  98. function test_newtab(testInfo) { // eslint-disable-line no-unused-vars
  99. // Extract any test parts or default to just the single content task
  100. let {before, test: contentTask, after} = testInfo;
  101. if (!before) {
  102. before = () => ({});
  103. }
  104. if (!contentTask) {
  105. contentTask = testInfo;
  106. }
  107. if (!after) {
  108. after = () => {};
  109. }
  110. // Helper to push prefs for just this test and pop them when done
  111. let needPopPrefs = false;
  112. let scopedPushPrefs = async (...args) => {
  113. needPopPrefs = true;
  114. await pushPrefs(...args);
  115. };
  116. let scopedPopPrefs = async () => {
  117. if (needPopPrefs) {
  118. await popPrefs();
  119. }
  120. };
  121. // Make the test task with optional before/after and content task to run in a
  122. // new tab that opens and closes.
  123. let testTask = async () => {
  124. // Open about:newtab without using the default load listener
  125. let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, "about:newtab", false);
  126. // Specially wait for potentially preloaded browsers
  127. let browser = tab.linkedBrowser;
  128. await waitForPreloaded(browser);
  129. // Add shared helpers to the content process
  130. ContentTask.spawn(browser, {}, addContentHelpers);
  131. // Wait for React to render something
  132. await BrowserTestUtils.waitForCondition(() => ContentTask.spawn(browser, {},
  133. () => content.document.getElementById("root").children.length),
  134. "Should render activity stream content");
  135. // Chain together before -> contentTask -> after data passing
  136. try {
  137. let contentArg = await before({pushPrefs: scopedPushPrefs, tab});
  138. let contentResult = await ContentTask.spawn(browser, contentArg, contentTask);
  139. await after(contentResult);
  140. } finally {
  141. // Clean up for next tests
  142. await scopedPopPrefs();
  143. BrowserTestUtils.removeTab(tab);
  144. }
  145. };
  146. // Copy the name of the content task to identify the test
  147. Object.defineProperty(testTask, "name", {value: contentTask.name});
  148. add_task(testTask);
  149. }