From d8bbc7858622b6d9c278469aab701ca0b609cddf Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 15 May 2024 05:35:49 +0200 Subject: Merging upstream version 126.0. Signed-off-by: Daniel Baumann --- toolkit/components/reader/.eslintrc.js | 2 +- toolkit/components/reader/AboutReader.sys.mjs | 241 ++++++++++++- toolkit/components/reader/ReaderMode.sys.mjs | 4 +- toolkit/components/reader/color-input.css | 47 +++ toolkit/components/reader/color-input.mjs | 69 ++++ toolkit/components/reader/color-input.stories.mjs | 32 ++ toolkit/components/reader/content/aboutReader.html | 71 +++- toolkit/components/reader/jar.mn | 2 + toolkit/components/reader/moz.build | 4 +- toolkit/components/reader/test/browser.toml | 76 ---- .../test/browser_bug1124271_readerModePinnedTab.js | 53 --- .../test/browser_bug1453818_samesite_cookie.js | 132 ------- .../browser_bug1780350_readerModeSaveScroll.js | 70 ---- .../reader/test/browser_drag_url_readerMode.js | 61 ---- .../reader/test/browser_localfile_readerMode.js | 54 --- .../components/reader/test/browser_readerMode.js | 399 --------------------- .../reader/test/browser_readerMode_bc_reuse.js | 44 --- .../reader/test/browser_readerMode_cached.js | 32 -- .../test/browser_readerMode_colorSchemePref.js | 67 ---- .../reader/test/browser_readerMode_hidden_nodes.js | 56 --- .../reader/test/browser_readerMode_menu.js | 69 ---- .../reader/test/browser_readerMode_pocket.js | 136 ------- .../reader/test/browser_readerMode_readingTime.js | 101 ------ .../reader/test/browser_readerMode_refresh.js | 49 --- .../reader/test/browser_readerMode_remoteType.js | 87 ----- .../browser_readerMode_samesite_cookie_redirect.js | 52 --- .../reader/test/browser_readerMode_with_anchor.js | 89 ----- toolkit/components/reader/test/getCookies.sjs | 16 - toolkit/components/reader/test/head.js | 59 --- .../components/reader/test/linkToGetCookies.html | 13 - .../components/reader/test/readerModeArticle.html | 28 -- .../reader/test/readerModeArticleContainsLink.html | 20 -- .../reader/test/readerModeArticleHiddenNodes.html | 22 -- .../reader/test/readerModeArticleMedium.html | 16 - .../reader/test/readerModeArticleShort.html | 14 - .../reader/test/readerModeArticleTextPlain.txt | 10 - .../reader/test/readerModeNonArticle.html | 9 - .../components/reader/test/readerModeRandom.sjs | 23 -- .../components/reader/test/setSameSiteCookie.html | 9 - .../reader/test/setSameSiteCookie.html^headers^ | 1 - .../components/reader/tests/browser/browser.toml | 76 ++++ .../browser_bug1124271_readerModePinnedTab.js | 53 +++ .../browser/browser_bug1453818_samesite_cookie.js | 132 +++++++ .../browser_bug1780350_readerModeSaveScroll.js | 70 ++++ .../tests/browser/browser_drag_url_readerMode.js | 61 ++++ .../tests/browser/browser_localfile_readerMode.js | 54 +++ .../reader/tests/browser/browser_readerMode.js | 399 +++++++++++++++++++++ .../tests/browser/browser_readerMode_bc_reuse.js | 44 +++ .../tests/browser/browser_readerMode_cached.js | 32 ++ .../browser/browser_readerMode_colorSchemePref.js | 121 +++++++ .../browser/browser_readerMode_hidden_nodes.js | 56 +++ .../tests/browser/browser_readerMode_menu.js | 75 ++++ .../tests/browser/browser_readerMode_pocket.js | 136 +++++++ .../browser/browser_readerMode_readingTime.js | 101 ++++++ .../tests/browser/browser_readerMode_refresh.js | 49 +++ .../tests/browser/browser_readerMode_remoteType.js | 87 +++++ .../browser_readerMode_samesite_cookie_redirect.js | 52 +++ .../browser/browser_readerMode_with_anchor.js | 89 +++++ .../components/reader/tests/browser/getCookies.sjs | 16 + toolkit/components/reader/tests/browser/head.js | 59 +++ .../reader/tests/browser/linkToGetCookies.html | 13 + .../reader/tests/browser/readerModeArticle.html | 28 ++ .../browser/readerModeArticleContainsLink.html | 20 ++ .../browser/readerModeArticleHiddenNodes.html | 22 ++ .../tests/browser/readerModeArticleMedium.html | 16 + .../tests/browser/readerModeArticleShort.html | 14 + .../tests/browser/readerModeArticleTextPlain.txt | 10 + .../reader/tests/browser/readerModeNonArticle.html | 9 + .../reader/tests/browser/readerModeRandom.sjs | 23 ++ .../reader/tests/browser/setSameSiteCookie.html | 9 + .../tests/browser/setSameSiteCookie.html^headers^ | 1 + toolkit/components/reader/tests/chrome/chrome.toml | 3 + .../reader/tests/chrome/test_color_input.html | 39 ++ 73 files changed, 2417 insertions(+), 1891 deletions(-) create mode 100644 toolkit/components/reader/color-input.css create mode 100644 toolkit/components/reader/color-input.mjs create mode 100644 toolkit/components/reader/color-input.stories.mjs delete mode 100644 toolkit/components/reader/test/browser.toml delete mode 100644 toolkit/components/reader/test/browser_bug1124271_readerModePinnedTab.js delete mode 100644 toolkit/components/reader/test/browser_bug1453818_samesite_cookie.js delete mode 100644 toolkit/components/reader/test/browser_bug1780350_readerModeSaveScroll.js delete mode 100644 toolkit/components/reader/test/browser_drag_url_readerMode.js delete mode 100644 toolkit/components/reader/test/browser_localfile_readerMode.js delete mode 100644 toolkit/components/reader/test/browser_readerMode.js delete mode 100644 toolkit/components/reader/test/browser_readerMode_bc_reuse.js delete mode 100644 toolkit/components/reader/test/browser_readerMode_cached.js delete mode 100644 toolkit/components/reader/test/browser_readerMode_colorSchemePref.js delete mode 100644 toolkit/components/reader/test/browser_readerMode_hidden_nodes.js delete mode 100644 toolkit/components/reader/test/browser_readerMode_menu.js delete mode 100644 toolkit/components/reader/test/browser_readerMode_pocket.js delete mode 100644 toolkit/components/reader/test/browser_readerMode_readingTime.js delete mode 100644 toolkit/components/reader/test/browser_readerMode_refresh.js delete mode 100644 toolkit/components/reader/test/browser_readerMode_remoteType.js delete mode 100644 toolkit/components/reader/test/browser_readerMode_samesite_cookie_redirect.js delete mode 100644 toolkit/components/reader/test/browser_readerMode_with_anchor.js delete mode 100644 toolkit/components/reader/test/getCookies.sjs delete mode 100644 toolkit/components/reader/test/head.js delete mode 100644 toolkit/components/reader/test/linkToGetCookies.html delete mode 100644 toolkit/components/reader/test/readerModeArticle.html delete mode 100644 toolkit/components/reader/test/readerModeArticleContainsLink.html delete mode 100644 toolkit/components/reader/test/readerModeArticleHiddenNodes.html delete mode 100644 toolkit/components/reader/test/readerModeArticleMedium.html delete mode 100644 toolkit/components/reader/test/readerModeArticleShort.html delete mode 100644 toolkit/components/reader/test/readerModeArticleTextPlain.txt delete mode 100644 toolkit/components/reader/test/readerModeNonArticle.html delete mode 100644 toolkit/components/reader/test/readerModeRandom.sjs delete mode 100644 toolkit/components/reader/test/setSameSiteCookie.html delete mode 100644 toolkit/components/reader/test/setSameSiteCookie.html^headers^ create mode 100644 toolkit/components/reader/tests/browser/browser.toml create mode 100644 toolkit/components/reader/tests/browser/browser_bug1124271_readerModePinnedTab.js create mode 100644 toolkit/components/reader/tests/browser/browser_bug1453818_samesite_cookie.js create mode 100644 toolkit/components/reader/tests/browser/browser_bug1780350_readerModeSaveScroll.js create mode 100644 toolkit/components/reader/tests/browser/browser_drag_url_readerMode.js create mode 100644 toolkit/components/reader/tests/browser/browser_localfile_readerMode.js create mode 100644 toolkit/components/reader/tests/browser/browser_readerMode.js create mode 100644 toolkit/components/reader/tests/browser/browser_readerMode_bc_reuse.js create mode 100644 toolkit/components/reader/tests/browser/browser_readerMode_cached.js create mode 100644 toolkit/components/reader/tests/browser/browser_readerMode_colorSchemePref.js create mode 100644 toolkit/components/reader/tests/browser/browser_readerMode_hidden_nodes.js create mode 100644 toolkit/components/reader/tests/browser/browser_readerMode_menu.js create mode 100644 toolkit/components/reader/tests/browser/browser_readerMode_pocket.js create mode 100644 toolkit/components/reader/tests/browser/browser_readerMode_readingTime.js create mode 100644 toolkit/components/reader/tests/browser/browser_readerMode_refresh.js create mode 100644 toolkit/components/reader/tests/browser/browser_readerMode_remoteType.js create mode 100644 toolkit/components/reader/tests/browser/browser_readerMode_samesite_cookie_redirect.js create mode 100644 toolkit/components/reader/tests/browser/browser_readerMode_with_anchor.js create mode 100644 toolkit/components/reader/tests/browser/getCookies.sjs create mode 100644 toolkit/components/reader/tests/browser/head.js create mode 100644 toolkit/components/reader/tests/browser/linkToGetCookies.html create mode 100644 toolkit/components/reader/tests/browser/readerModeArticle.html create mode 100644 toolkit/components/reader/tests/browser/readerModeArticleContainsLink.html create mode 100644 toolkit/components/reader/tests/browser/readerModeArticleHiddenNodes.html create mode 100644 toolkit/components/reader/tests/browser/readerModeArticleMedium.html create mode 100644 toolkit/components/reader/tests/browser/readerModeArticleShort.html create mode 100644 toolkit/components/reader/tests/browser/readerModeArticleTextPlain.txt create mode 100644 toolkit/components/reader/tests/browser/readerModeNonArticle.html create mode 100644 toolkit/components/reader/tests/browser/readerModeRandom.sjs create mode 100644 toolkit/components/reader/tests/browser/setSameSiteCookie.html create mode 100644 toolkit/components/reader/tests/browser/setSameSiteCookie.html^headers^ create mode 100644 toolkit/components/reader/tests/chrome/chrome.toml create mode 100644 toolkit/components/reader/tests/chrome/test_color_input.html (limited to 'toolkit/components/reader') diff --git a/toolkit/components/reader/.eslintrc.js b/toolkit/components/reader/.eslintrc.js index 4df95dd5f8..bf83f31ab1 100644 --- a/toolkit/components/reader/.eslintrc.js +++ b/toolkit/components/reader/.eslintrc.js @@ -8,6 +8,6 @@ module.exports = { rules: { "no-inner-declarations": "error", "no-shadow": "error", - "no-unused-vars": ["error", { vars: "all", args: "none" }], + "no-unused-vars": ["error", { vars: "all", argsIgnorePattern: "^_" }], }, }; diff --git a/toolkit/components/reader/AboutReader.sys.mjs b/toolkit/components/reader/AboutReader.sys.mjs index 6b1c28c228..75776b619f 100644 --- a/toolkit/components/reader/AboutReader.sys.mjs +++ b/toolkit/components/reader/AboutReader.sys.mjs @@ -8,6 +8,7 @@ import { AppConstants } from "resource://gre/modules/AppConstants.sys.mjs"; const lazy = {}; let gScrollPositions = new Map(); +let lastSelectedTheme = "auto"; ChromeUtils.defineESModuleGetters(lazy, { AsyncPrefs: "resource://gre/modules/AsyncPrefs.sys.mjs", @@ -26,10 +27,31 @@ ChromeUtils.defineLazyGetter( ); const COLORSCHEME_L10N_IDS = { - light: "about-reader-color-scheme-light", - dark: "about-reader-color-scheme-dark", - sepia: "about-reader-color-scheme-sepia", - auto: "about-reader-color-scheme-auto", + auto: "about-reader-color-theme-auto", + light: "about-reader-color-theme-light", + dark: "about-reader-color-theme-dark", + sepia: "about-reader-color-theme-sepia", + contrast: "about-reader-color-theme-contrast", + gray: "about-reader-color-theme-gray", + custom: "about-reader-color-theme-custom", +}; + +const CUSTOM_THEME_COLOR_INPUTS = [ + "foreground", + "background", + "unvisited-links", + "visited-links", + "selection-highlight", +]; + +const COLORS_MENU_TABS = ["fxtheme", "customtheme"]; + +const DEFAULT_COLORS = { + background: "#FFFFFF", + foreground: "#14151A", + "unvisited-links": "#0060DF", + "visited-links": "#321C64", + "selection-highlight": "#FFFFCC", }; Services.telemetry.setEventRecordingEnabled("readermode", true); @@ -147,9 +169,27 @@ export var AboutReader = function ( // we're ready for any external setup, send a signal for that. this._actor.sendAsyncMessage("Reader:OnSetup"); - let colorSchemeValues = JSON.parse( + // set up segmented tab controls for colors menu. + this._setupColorsTabs( + COLORS_MENU_TABS, + this._handleColorsTabClick.bind(this) + ); + + // fetch color scheme values from prefs. + let colorsMenuColorSchemeValues = JSON.parse( Services.prefs.getCharPref("reader.color_scheme.values") ); + // remove contrast and gray options from regular menu. + let colorSchemeValues = [...colorsMenuColorSchemeValues]; + colorSchemeValues.splice(colorSchemeValues.length - 2, 2); + + let colorsMenuColorSchemeOptions = colorsMenuColorSchemeValues.map(value => ({ + l10nId: COLORSCHEME_L10N_IDS[value], + groupName: "color-scheme", + value, + itemClass: value + "-button", + })); + let colorSchemeOptions = colorSchemeValues.map(value => ({ l10nId: COLORSCHEME_L10N_IDS[value], groupName: "color-scheme", @@ -158,12 +198,33 @@ export var AboutReader = function ( })); let colorScheme = Services.prefs.getCharPref("reader.color_scheme"); - this._setupSegmentedButton( - "color-scheme-buttons", - colorSchemeOptions, - colorScheme, - this._setColorSchemePref.bind(this) - ); + if (Services.prefs.getBoolPref("reader.colors_menu.enabled", false)) { + doc.getElementById("regular-color-scheme").hidden = true; + doc.getElementById("custom-colors-color-scheme").hidden = false; + this._setupSegmentedButton( + "colors-menu-color-scheme-buttons", + colorsMenuColorSchemeOptions, + colorScheme, + this._setColorSchemePref.bind(this) + ); + this._setupCustomColors( + CUSTOM_THEME_COLOR_INPUTS, + "custom-colors-selection", + "about-reader-custom-colors" + ); + this._setupButton( + "custom-colors-reset-button", + this._resetCustomColors.bind(this) + ); + } else { + this._setupSegmentedButton( + "color-scheme-buttons", + colorSchemeOptions, + colorScheme, + this._setColorSchemePref.bind(this) + ); + } + this._setColorSchemePref(colorScheme); let fontTypeOptions = [ @@ -738,19 +799,43 @@ AboutReader.prototype = { this._colorScheme = "hcm"; } + if (this._colorScheme == "custom") { + const colorInputs = this._doc.querySelectorAll("color-input"); + colorInputs.forEach(input => { + // Set document body styles to pref values. + let property = input.getAttribute("prop-name"); + let pref = `reader.custom_colors.${property}`; + let customColor = Services.prefs.getStringPref(pref, ""); + // If customColor is truthy, set the value from pref. + if (customColor) { + let cssProp = `--custom-theme-${property}`; + this._doc.body.style.setProperty(cssProp, customColor); + } + }); + } + bodyClasses.add(this._colorScheme); }, - // Pref values include "dark", "light", "sepia", and "auto" - _setColorSchemePref(colorSchemePref) { + // Pref values include "auto", "dark", "light", "sepia", + // "gray", "contrast", and "custom" + _setColorSchemePref(colorSchemePref, fromInputEvent = false) { + // The input event for the last selected segmented button is fired + // upon loading a reader article in the same session. To prevent it + // from overwriting custom colors, we return false. + if (this._colorScheme == "custom" && fromInputEvent) { + lastSelectedTheme = colorSchemePref; + return false; + } this._setColorScheme(colorSchemePref); lazy.AsyncPrefs.set("reader.color_scheme", colorSchemePref); + return true; }, _setFontType(newFontType) { if (this._fontType === newFontType) { - return; + return false; } let bodyClasses = this._doc.body.classList; @@ -763,6 +848,8 @@ AboutReader.prototype = { bodyClasses.add(this._fontType); lazy.AsyncPrefs.set("reader.font_type", this._fontType); + + return true; }, async _loadArticle(docContentType = "document") { @@ -1094,14 +1181,17 @@ AboutReader.prototype = { label.removeAttribute("checked"); } - aEvent.target.nextElementSibling.setAttribute("checked", "true"); - callback(option.value); + let setOption = callback(option.value, true); + if (setOption) { + aEvent.target.setAttribute("checked", "true"); + aEvent.target.nextElementSibling.setAttribute("checked", "true"); + } }, true ); if (option.value === initialValue) { - radioButton.checked = true; + radioButton.setAttribute("checked", "true"); item.setAttribute("checked", "true"); } } @@ -1124,6 +1214,121 @@ AboutReader.prototype = { ); }, + _handleColorsTabClick(option) { + let doc = this._doc; + if (option == "customtheme") { + this._setColorSchemePref("custom"); + lazy.AsyncPrefs.set("reader.color_scheme", "custom"); + + // Store the last selected preset theme button. + const colorSchemePresets = doc.querySelector( + ".colors-menu-color-scheme-buttons" + ); + const labels = colorSchemePresets.querySelectorAll("label"); + labels.forEach(label => { + if (label.hasAttribute("checked")) { + lastSelectedTheme = label.className.split("-")[0]; + } + }); + } + if (option == "fxtheme") { + this._setColorSchemePref(lastSelectedTheme); + lazy.AsyncPrefs.set("reader.color_scheme", lastSelectedTheme); + // set the last selected button to checked. + const colorSchemePresets = doc.querySelector( + ".colors-menu-color-scheme-buttons" + ); + const labels = colorSchemePresets.querySelectorAll("label"); + labels.forEach(label => { + if (label.className == `${lastSelectedTheme}-button`) { + label.setAttribute("checked", "true"); + label.previousElementSibling.setAttribute("checked", "true"); + } + }); + } + }, + + _setupColorsTabs(options, callback) { + let doc = this._doc; + let colorScheme = Services.prefs.getCharPref("reader.color_scheme"); + for (let option of options) { + let tabButton = doc.getElementById(`tabs-deck-button-${option}`); + // Open custom theme tab if color scheme is set to custom. + if (option == "customtheme" && colorScheme == "custom") { + tabButton.click(); + } + tabButton.addEventListener( + "click", + function (aEvent) { + if (!aEvent.isTrusted) { + return; + } + + callback(option); + }, + true + ); + } + }, + + _setupColorInput(prop) { + let doc = this._doc; + let input = doc.createElement("color-input"); + input.setAttribute("prop-name", prop); + let labelL10nId = `about-reader-custom-colors-${prop}`; + input.setAttribute("data-l10n-id", labelL10nId); + + let pref = `reader.custom_colors.${prop}`; + let customColor = Services.prefs.getStringPref(pref, ""); + // Set the swatch color from prefs if one has been set. + if (customColor) { + input.setAttribute("color", customColor); + } else { + let defaultColor = DEFAULT_COLORS[prop]; + input.setAttribute("color", defaultColor); + } + + // Attach event listener to update the pref and page colors on input. + input.addEventListener("color-picked", e => { + const cssPropToUpdate = `--custom-theme-${prop}`; + this._doc.body.style.setProperty(cssPropToUpdate, e.detail); + + const prefToUpdate = `reader.custom_colors.${prop}`; + lazy.AsyncPrefs.set(prefToUpdate, e.detail); + }); + + return input; + }, + + _setupCustomColors(options, id) { + let doc = this._doc; + const list = doc.getElementsByClassName(id)[0]; + + for (let option of options) { + let listItem = doc.createElement("li"); + let colorInput = this._setupColorInput(option); + listItem.appendChild(colorInput); + list.appendChild(listItem); + } + }, + + _resetCustomColors() { + // Need to reset prefs, page colors, and color inputs. + const colorInputs = this._doc.querySelectorAll("color-input"); + colorInputs.forEach(input => { + let property = input.getAttribute("prop-name"); + let pref = `reader.custom_colors.${property}`; + lazy.AsyncPrefs.set(pref, ""); + + // Set css props to empty strings so they use fallback value. + let cssProp = `--custom-theme-${property}`; + this._doc.body.style.setProperty(cssProp, ""); + + let defaultColor = DEFAULT_COLORS[property]; + input.setAttribute("color", defaultColor); + }); + }, + _toggleDropdownClicked(event) { let dropdown = event.target.closest(".dropdown"); @@ -1143,7 +1348,7 @@ AboutReader.prototype = { /* * If the ReaderView banner font-dropdown is closed, open it. */ - _openDropdown(dropdown, window) { + _openDropdown(dropdown) { if (dropdown.classList.contains("open")) { return; } diff --git a/toolkit/components/reader/ReaderMode.sys.mjs b/toolkit/components/reader/ReaderMode.sys.mjs index 4b754d88b0..c2561bfb23 100644 --- a/toolkit/components/reader/ReaderMode.sys.mjs +++ b/toolkit/components/reader/ReaderMode.sys.mjs @@ -273,11 +273,11 @@ export var ReaderMode = { "READER_MODE_DOWNLOAD_RESULT" ); return new Promise((resolve, reject) => { - let xhr = new XMLHttpRequest(); + let xhr = new XMLHttpRequest({ mozAnon: false }); xhr.open("GET", url, true); xhr.onerror = evt => reject(evt.error); xhr.responseType = docContentType === "text/plain" ? "text" : "document"; - xhr.onload = evt => { + xhr.onload = () => { if (xhr.status !== 200) { reject("Reader mode XHR failed with status: " + xhr.status); histogram.add(DOWNLOAD_ERROR_XHR); diff --git a/toolkit/components/reader/color-input.css b/toolkit/components/reader/color-input.css new file mode 100644 index 0000000000..93e269dd16 --- /dev/null +++ b/toolkit/components/reader/color-input.css @@ -0,0 +1,47 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +.color-input-container { + display: flex; + position: relative; + justify-content: flex-start; + align-items: center; + gap: var(--space-small); + min-height: 46px; + border: 1px solid rgba(0, 0, 0, 0.2); + padding: 0 var(--space-small); + border-radius: var(--border-radius-small); +} + +.color-input-container:hover { + background-color: var(--toolbar-button-background-hover); +} + +#color-swatch:focus-visible { + outline: none; +} + +.color-input-container:focus-within { + outline: 2px solid var(--primary-color); + outline-offset: var(--focus-outline-offset); +} + +.icon-container { + display: flex; + margin-inline: auto var(--space-xsmall); +} + +#color-swatch { + appearance: none; + width: 34px; + height: 34px; + background-color: transparent; + border: none; + cursor: pointer; +} + +#color-swatch::-moz-color-swatch { + border-radius: var(--border-radius-circle); + border: 1px solid rgba(0, 0, 0, 0.25); +} diff --git a/toolkit/components/reader/color-input.mjs b/toolkit/components/reader/color-input.mjs new file mode 100644 index 0000000000..1c460dac3e --- /dev/null +++ b/toolkit/components/reader/color-input.mjs @@ -0,0 +1,69 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +import { html } from "chrome://global/content/vendor/lit.all.mjs"; +import { MozLitElement } from "chrome://global/content/lit-utils.mjs"; + +/** + * @tagname color-input + * @property {string} color - The initial color value as a hex code. + * @property {string} propName - The property that the color input sets. + * @property {string} l10nId - l10nId for label text. + */ +export default class ColorInput extends MozLitElement { + static properties = { + color: { type: String }, + propName: { type: String, attribute: "prop-name" }, + l10nId: { type: String, attribute: "data-l10n-id" }, + }; + + static queries = { + inputEl: "#color-swatch", + }; + + handleColorInput(event) { + this.color = event.target.value; + this.dispatchEvent( + new CustomEvent("color-picked", { + detail: this.color, + }) + ); + } + + /* Function to launch color picker when the user clicks anywhere in the container. */ + handleClick(event) { + // If the user directly clicks the color swatch, no need to propagate click. + if (event.target.matches("input")) { + return; + } + this.inputEl.click(); + } + + render() { + return html` + +
+ + +
+ +
+
+ `; + } +} +customElements.define("color-input", ColorInput); diff --git a/toolkit/components/reader/color-input.stories.mjs b/toolkit/components/reader/color-input.stories.mjs new file mode 100644 index 0000000000..cec85a8d98 --- /dev/null +++ b/toolkit/components/reader/color-input.stories.mjs @@ -0,0 +1,32 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +import { html } from "../../content/widgets/vendor/lit.all.mjs"; +// eslint-disable-next-line import/no-unassigned-import +import "chrome://global/content/reader/color-input.mjs"; + +export default { + title: "Domain-specific UI Widgets/Reader View/Color Input", + component: "color-input", + argTypes: {}, + parameters: { + status: "stable", + fluent: `moz-color-input-label = Background`, + }, +}; + +const Template = ({ color, propName, labelL10nId }) => html` + +`; + +export const Default = Template.bind({}); +Default.args = { + propName: "background", + color: "#7293C9", + labelL10nId: "moz-color-input-label", +}; diff --git a/toolkit/components/reader/content/aboutReader.html b/toolkit/components/reader/content/aboutReader.html index db93e9f80b..d1c9164d42 100644 --- a/toolkit/components/reader/content/aboutReader.html +++ b/toolkit/components/reader/content/aboutReader.html @@ -12,6 +12,10 @@ /> + + + @@ -53,7 +65,6 @@ + + diff --git a/toolkit/components/reader/jar.mn b/toolkit/components/reader/jar.mn index 4b72136192..587dd45cf8 100644 --- a/toolkit/components/reader/jar.mn +++ b/toolkit/components/reader/jar.mn @@ -4,3 +4,5 @@ toolkit.jar: content/global/reader/aboutReader.html (content/aboutReader.html) + content/global/reader/color-input.css (color-input.css) + content/global/reader/color-input.mjs (color-input.mjs) diff --git a/toolkit/components/reader/moz.build b/toolkit/components/reader/moz.build index e57a0fe705..dba7a5a2ef 100644 --- a/toolkit/components/reader/moz.build +++ b/toolkit/components/reader/moz.build @@ -22,7 +22,9 @@ EXTRA_JS_MODULES.reader = [ "ReaderWorker.sys.mjs", ] -BROWSER_CHROME_MANIFESTS += ["test/browser.toml"] +BROWSER_CHROME_MANIFESTS += ["tests/browser/browser.toml"] + +MOCHITEST_CHROME_MANIFESTS += ["tests/chrome/chrome.toml"] with Files("**"): BUG_COMPONENT = ("Toolkit", "Reader Mode") diff --git a/toolkit/components/reader/test/browser.toml b/toolkit/components/reader/test/browser.toml deleted file mode 100644 index 9382e6d60f..0000000000 --- a/toolkit/components/reader/test/browser.toml +++ /dev/null @@ -1,76 +0,0 @@ -[DEFAULT] -support-files = ["head.js"] - -["browser_bug1124271_readerModePinnedTab.js"] -support-files = ["readerModeArticle.html"] - -["browser_bug1453818_samesite_cookie.js"] -support-files = [ - "getCookies.sjs", - "linkToGetCookies.html", - "setSameSiteCookie.html", - "setSameSiteCookie.html^headers^", -] - -["browser_bug1780350_readerModeSaveScroll.js"] -support-files = ["readerModeArticleContainsLink.html"] - -["browser_drag_url_readerMode.js"] -support-files = ["readerModeArticle.html"] - -["browser_localfile_readerMode.js"] -support-files = ["readerModeArticle.html"] - -["browser_readerMode.js"] -support-files = [ - "readerModeNonArticle.html", - "readerModeArticle.html", - "readerModeArticleHiddenNodes.html", -] - -["browser_readerMode_bc_reuse.js"] -support-files = ["readerModeArticle.html"] - -["browser_readerMode_cached.js"] -support-files = ["readerModeRandom.sjs"] - -["browser_readerMode_colorSchemePref.js"] -support-files = ["readerModeArticle.html"] - -["browser_readerMode_hidden_nodes.js"] -support-files = ["readerModeArticleHiddenNodes.html"] - -["browser_readerMode_menu.js"] -support-files = ["readerModeArticleShort.html"] - -["browser_readerMode_pocket.js"] -support-files = [ - "readerModeArticleShort.html", - "readerModeArticleMedium.html", -] - -["browser_readerMode_readingTime.js"] -support-files = [ - "readerModeArticle.html", - "readerModeArticleShort.html", - "readerModeArticleMedium.html", -] - -["browser_readerMode_refresh.js"] -support-files = [ - "readerModeArticleShort.html", - "readerModeArticleTextPlain.txt", -] - -["browser_readerMode_remoteType.js"] -support-files = ["readerModeArticleShort.html"] - -["browser_readerMode_samesite_cookie_redirect.js"] -support-files = [ - "getCookies.sjs", - "setSameSiteCookie.html", - "setSameSiteCookie.html^headers^", -] - -["browser_readerMode_with_anchor.js"] -support-files = ["readerModeArticle.html"] diff --git a/toolkit/components/reader/test/browser_bug1124271_readerModePinnedTab.js b/toolkit/components/reader/test/browser_bug1124271_readerModePinnedTab.js deleted file mode 100644 index 346d503675..0000000000 --- a/toolkit/components/reader/test/browser_bug1124271_readerModePinnedTab.js +++ /dev/null @@ -1,53 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -// Test that the reader mode button won't open in a new tab when clicked from a pinned tab - -const PREF = "reader.parse-on-load.enabled"; - -const TEST_PATH = getRootDirectory(gTestPath).replace( - "chrome://mochitests/content", - "https://example.com" -); - -var readerButton = document.getElementById("reader-mode-button"); - -add_task(async function () { - registerCleanupFunction(function () { - Services.prefs.clearUserPref(PREF); - while (gBrowser.tabs.length > 1) { - gBrowser.removeCurrentTab(); - } - }); - - // Enable the reader mode button. - Services.prefs.setBoolPref(PREF, true); - - let tab = (gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser)); - gBrowser.pinTab(tab); - - let initialTabsCount = gBrowser.tabs.length; - - // Point tab to a test page that is reader-able. - let url = TEST_PATH + "readerModeArticle.html"; - await promiseTabLoadEvent(tab, url); - await TestUtils.waitForCondition(() => !readerButton.hidden); - - readerButton.click(); - await promiseTabLoadEvent(tab); - - // Ensure no new tabs are opened when exiting reader mode in a pinned tab - is(gBrowser.tabs.length, initialTabsCount, "No additional tabs were opened."); - - let pageShownPromise = BrowserTestUtils.waitForContentEvent( - tab.linkedBrowser, - "pageshow" - ); - readerButton.click(); - await pageShownPromise; - // Ensure no new tabs are opened when exiting reader mode in a pinned tab - is(gBrowser.tabs.length, initialTabsCount, "No additional tabs were opened."); - - gBrowser.removeCurrentTab(); -}); diff --git a/toolkit/components/reader/test/browser_bug1453818_samesite_cookie.js b/toolkit/components/reader/test/browser_bug1453818_samesite_cookie.js deleted file mode 100644 index 1fbfdeabfb..0000000000 --- a/toolkit/components/reader/test/browser_bug1453818_samesite_cookie.js +++ /dev/null @@ -1,132 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -"use strict"; - -const TEST_ORIGIN1 = getRootDirectory(gTestPath).replace( - "chrome://mochitests/content", - "http://example.com" -); -const TEST_ORIGIN2 = getRootDirectory(gTestPath).replace( - "chrome://mochitests/content", - "http://example.org" -); - -async function clickLink(browser) { - info("Waiting for the page to load after clicking the link..."); - let pageLoaded = BrowserTestUtils.waitForContentEvent( - browser, - "DOMContentLoaded" - ); - await SpecialPowers.spawn(browser, [], async function () { - let link = content.document.getElementById("link"); - ok(link, "The link element was found."); - link.click(); - }); - await pageLoaded; -} - -async function checkCookiePresent(browser) { - await SpecialPowers.spawn(browser, [], async function () { - let cookieSpan = content.document.getElementById("cookieSpan"); - ok(cookieSpan, "cookieSpan element should be in document"); - is( - cookieSpan.textContent, - "foo=bar", - "The SameSite cookie was sent correctly." - ); - }); -} - -async function checkCookie(browser) { - info("Check that the SameSite cookie was not sent."); - await SpecialPowers.spawn(browser, [], async function () { - let cookieSpan = content.document.getElementById("cookieSpan"); - ok(cookieSpan, "cookieSpan element should be in document"); - is( - cookieSpan.textContent, - "", - "The SameSite cookie was blocked correctly." - ); - }); -} - -async function runTest() { - await SpecialPowers.pushPrefEnv({ - set: [["reader.parse-on-load.enabled", true]], - }); - - info("Set a SameSite=strict cookie."); - await BrowserTestUtils.withNewTab( - TEST_ORIGIN1 + "setSameSiteCookie.html", - () => {} - ); - - info("Check that the cookie has been correctly set."); - await BrowserTestUtils.withNewTab( - TEST_ORIGIN1 + "getCookies.sjs", - async function (browser) { - await checkCookiePresent(browser); - } - ); - - info( - "Open a cross-origin page with a link to the domain that set the cookie." - ); - { - let browser; - let pageLoaded; - let tab = await BrowserTestUtils.openNewForegroundTab( - gBrowser, - () => { - let t = BrowserTestUtils.addTab( - gBrowser, - TEST_ORIGIN2 + "linkToGetCookies.html" - ); - gBrowser.selectedTab = t; - browser = gBrowser.selectedBrowser; - pageLoaded = BrowserTestUtils.waitForContentEvent( - browser, - "DOMContentLoaded" - ); - return t; - }, - false - ); - - info("Waiting for the page to load in normal mode..."); - await pageLoaded; - - await clickLink(browser); - await checkCookie(browser); - await BrowserTestUtils.removeTab(tab); - } - - info("Open the cross-origin page again."); - await BrowserTestUtils.withNewTab( - TEST_ORIGIN2 + "linkToGetCookies.html", - async function (browser) { - let pageShown = BrowserTestUtils.waitForContentEvent( - browser, - "AboutReaderContentReady" - ); - let readerButton = document.getElementById("reader-mode-button"); - ok(readerButton, "readerButton should be available"); - readerButton.click(); - - info("Waiting for the page to be displayed in reader mode..."); - await pageShown; - - await clickLink(browser); - await checkCookie(browser); - } - ); -} - -add_task(async function () { - await runTest(true); -}); - -add_task(async function () { - await runTest(false); -}); diff --git a/toolkit/components/reader/test/browser_bug1780350_readerModeSaveScroll.js b/toolkit/components/reader/test/browser_bug1780350_readerModeSaveScroll.js deleted file mode 100644 index 76add5511e..0000000000 --- a/toolkit/components/reader/test/browser_bug1780350_readerModeSaveScroll.js +++ /dev/null @@ -1,70 +0,0 @@ -/* eslint-disable @microsoft/sdl/no-insecure-url */ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ -"use strict"; - -const TEST_PATH = getRootDirectory(gTestPath).replace( - "chrome://mochitests/content", - "http://example.com" -); - -// This test verifies that when a link is clicked from -// within reader view, when navigating back to reader view -// the previous scroll position of the page is restored. -add_task(async function test_save_scroll_position() { - await BrowserTestUtils.withNewTab( - TEST_PATH + "readerModeArticleContainsLink.html", - async function (browser) { - let pageShownPromise = BrowserTestUtils.waitForContentEvent( - browser, - "AboutReaderContentReady" - ); - let browserLoadedPromise = BrowserTestUtils.browserLoaded(browser); - let readerButton = document.getElementById("reader-mode-button"); - readerButton.click(); - await Promise.all([pageShownPromise, browserLoadedPromise]); - let scrollEventPromise = BrowserTestUtils.waitForContentEvent( - browser, - "scroll", - true - ); - // Set scroll position in reader to 200px down. - await SpecialPowers.spawn(browser, [], async function () { - content.document.documentElement.scrollTop = 200; - }); - await scrollEventPromise; - - // Click linked page and check that scroll pos resets. - await SpecialPowers.spawn(browser, [], async function () { - let linkElement = content.document.getElementById("link"); - linkElement.click(); - }); - await BrowserTestUtils.browserLoaded(browser); - await SpecialPowers.spawn(browser, [], async function () { - is( - content.document.documentElement.scrollTop, - 0, - "vertical scroll position should reset to zero when navigating to linked page." - ); - content.window.history.back(); - }); - - // Navigate back to reader and check that scroll position is restored. - await BrowserTestUtils.browserLoaded(browser); - scrollEventPromise = BrowserTestUtils.waitForContentEvent( - browser, - "scroll", - true - ); - await scrollEventPromise; - await SpecialPowers.spawn(browser, [], async function () { - let doc = content.document; - is( - doc.documentElement.scrollTop, - 200, - "should restore saved scroll position when navigating back from link." - ); - }); - } - ); -}); diff --git a/toolkit/components/reader/test/browser_drag_url_readerMode.js b/toolkit/components/reader/test/browser_drag_url_readerMode.js deleted file mode 100644 index 2dae1872c3..0000000000 --- a/toolkit/components/reader/test/browser_drag_url_readerMode.js +++ /dev/null @@ -1,61 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -"use strict"; - -const TEST_PATH = getRootDirectory(gTestPath).replace( - "chrome://mochitests/content", - "http://example.com" -); - -add_task(async function test_readerModeURLDrag() { - await BrowserTestUtils.withNewTab( - { - gBrowser, - url: TEST_PATH + "readerModeArticle.html", - }, - - async browser => { - let readerButton = document.getElementById("reader-mode-button"); - await TestUtils.waitForCondition( - () => !readerButton.hidden, - "Reader mode button should become visible" - ); - - is_element_visible( - readerButton, - "Reader mode button is present on a reader-able page" - ); - - // Switch page into reader mode. - let promiseTabLoad = BrowserTestUtils.browserLoaded(browser); - readerButton.click(); - await promiseTabLoad; - let urlbar = document.getElementById("urlbar-input"); - let readerUrl = gBrowser.selectedBrowser.currentURI.spec; - ok( - readerUrl.startsWith("about:reader"), - "about:reader loaded after clicking reader mode button" - ); - - let dataTran = new DataTransfer(); - let urlEvent = new DragEvent("dragstart", { dataTransfer: dataTran }); - let oldUrl = TEST_PATH + "readerModeArticle.html"; - let urlBarContainer = document.getElementById("urlbar-input-container"); - // We intentionally turn off a11y_checks for the following click, because - // it is send to prepare the URL Bar for the mouse-specific action - for a - // drag event, while there are other ways are accessible for users of - // assistive technology and keyboards, therefore this test can be excluded - // from the accessibility tests. - AccessibilityUtils.setEnv({ mustHaveAccessibleRule: false }); - urlBarContainer.click(); - AccessibilityUtils.resetEnv(); - urlbar.dispatchEvent(urlEvent); - - let newUrl = urlEvent.dataTransfer.getData("text/plain"); - ok(!newUrl.includes("about:reader"), "URL does not contain about:reader"); - - Assert.equal(newUrl, oldUrl, "URL is the same"); - } - ); -}); diff --git a/toolkit/components/reader/test/browser_localfile_readerMode.js b/toolkit/components/reader/test/browser_localfile_readerMode.js deleted file mode 100644 index 118e4bb23f..0000000000 --- a/toolkit/components/reader/test/browser_localfile_readerMode.js +++ /dev/null @@ -1,54 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -"use strict"; - -const TEST_BASE_URI = getResolvedURI(getRootDirectory(gTestPath)).spec; - -let readerButton = document.getElementById("reader-mode-button"); - -/** - * Reader mode should work on local files. - */ -add_task(async function test_readermode_available_for_local_files() { - await BrowserTestUtils.withNewTab( - TEST_BASE_URI + "readerModeArticle.html", - async function (browser) { - await TestUtils.waitForCondition( - () => !readerButton.hidden, - "Reader mode button should become visible" - ); - - is_element_visible( - readerButton, - "Reader mode button is present on a reader-able page" - ); - - // Switch page into reader mode. - let promiseTabLoad = BrowserTestUtils.browserLoaded(browser); - readerButton.click(); - await promiseTabLoad; - - let readerUrl = gBrowser.selectedBrowser.currentURI.spec; - ok( - readerUrl.startsWith("about:reader"), - "about:reader loaded after clicking reader mode button" - ); - is_element_visible( - readerButton, - "Reader mode button is present on about:reader" - ); - - is( - gURLBar.untrimmedValue, - TEST_BASE_URI + "readerModeArticle.html", - "gURLBar value is about:reader URL" - ); - is( - gURLBar.value, - gURLBar.untrimmedValue, - "gURLBar is displaying original article URL" - ); - } - ); -}); diff --git a/toolkit/components/reader/test/browser_readerMode.js b/toolkit/components/reader/test/browser_readerMode.js deleted file mode 100644 index a38e0a6de6..0000000000 --- a/toolkit/components/reader/test/browser_readerMode.js +++ /dev/null @@ -1,399 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/** - * Test that the reader mode button appears and works properly on - * reader-able content. - */ -const TEST_PREFS = [["reader.parse-on-load.enabled", true]]; - -const TEST_PATH = getRootDirectory(gTestPath).replace( - "chrome://mochitests/content", - "https://example.com" -); - -var readerButton = document.getElementById("reader-mode-button"); - -ChromeUtils.defineESModuleGetters(this, { - PlacesTestUtils: "resource://testing-common/PlacesTestUtils.sys.mjs", - UrlbarTestUtils: "resource://testing-common/UrlbarTestUtils.sys.mjs", -}); - -add_task(async function test_reader_button() { - registerCleanupFunction(function () { - // Reset test prefs. - TEST_PREFS.forEach(([name, value]) => { - Services.prefs.clearUserPref(name); - }); - while (gBrowser.tabs.length > 1) { - gBrowser.removeCurrentTab(); - } - }); - - // Set required test prefs. - TEST_PREFS.forEach(([name, value]) => { - Services.prefs.setBoolPref(name, value); - }); - - let tab = (gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser)); - is_element_hidden( - readerButton, - "Reader mode button is not present on a new tab" - ); - ok( - !UITour.isInfoOnTarget(window, "readerMode-urlBar"), - "Info panel shouldn't appear without the reader mode button" - ); - - // Point tab to a test page that is reader-able. - let url = TEST_PATH + "readerModeArticle.html"; - // Set up favicon for testing. - let favicon = - "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAA" + - "AAAA6fptVAAAACklEQVQI12NgAAAAAgAB4iG8MwAAAABJRU5ErkJggg=="; - info("Adding visit so we can add favicon"); - await PlacesTestUtils.addVisits(new URL(url)); - info("Adding favicon"); - await PlacesTestUtils.addFavicons(new Map([[url, favicon]])); - info("Opening tab and waiting for reader mode button to show up"); - - await promiseTabLoadEvent(tab, url); - await TestUtils.waitForCondition(() => !readerButton.hidden); - - is_element_visible( - readerButton, - "Reader mode button is present on a reader-able page" - ); - - // Switch page into reader mode. - let promiseTabLoad = promiseTabLoadEvent(tab); - readerButton.click(); - await promiseTabLoad; - - let readerUrl = gBrowser.selectedBrowser.currentURI.spec; - ok( - readerUrl.startsWith("about:reader"), - "about:reader loaded after clicking reader mode button" - ); - is_element_visible( - readerButton, - "Reader mode button is present on about:reader" - ); - let iconEl = tab.iconImage; - await TestUtils.waitForCondition( - () => iconEl.getBoundingClientRect().width != 0 - ); - is_element_visible(iconEl, "Favicon should be visible"); - is(iconEl.src, favicon, "Correct favicon should be loaded"); - - is(gURLBar.untrimmedValue, url, "gURLBar value is about:reader URL"); - is( - gURLBar.value, - UrlbarTestUtils.trimURL(url), - "gURLBar is displaying original article URL" - ); - - // Check selected value for URL bar - await new Promise((resolve, reject) => { - waitForClipboard( - url, - function () { - gURLBar.focus(); - gURLBar.select(); - goDoCommand("cmd_copy"); - }, - resolve, - reject - ); - }); - - info("Got correct URL when copying"); - - // Switch page back out of reader mode. - let promisePageShow = BrowserTestUtils.waitForContentEvent( - tab.linkedBrowser, - "pageshow", - false, - e => e.target.location.href != "about:blank" - ); - readerButton.click(); - await promisePageShow; - is( - gBrowser.selectedBrowser.currentURI.spec, - url, - "Back to the original page after clicking active reader mode button" - ); - ok( - gBrowser.selectedBrowser.canGoForward, - "Moved one step back in the session history." - ); - - let nonReadableUrl = TEST_PATH + "readerModeNonArticle.html"; - - // Load a new tab that is NOT reader-able. - let newTab = (gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser)); - await promiseTabLoadEvent(newTab, nonReadableUrl); - await TestUtils.waitForCondition(() => readerButton.hidden); - is_element_hidden( - readerButton, - "Reader mode button is not present on a non-reader-able page" - ); - - // Switch back to the original tab to make sure reader mode button is still visible. - gBrowser.removeCurrentTab(); - await TestUtils.waitForCondition(() => !readerButton.hidden); - is_element_visible( - readerButton, - "Reader mode button is present on a reader-able page" - ); - - // Load a new tab in reader mode that is NOT reader-able in the reader mode. - newTab = gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser); - let promiseAboutReaderError = BrowserTestUtils.waitForContentEvent( - newTab.linkedBrowser, - "AboutReaderContentError" - ); - await promiseTabLoadEvent(newTab, "about:reader?url=" + nonReadableUrl); - await promiseAboutReaderError; - await TestUtils.waitForCondition(() => !readerButton.hidden); - is_element_visible( - readerButton, - "Reader mode button is present on about:reader even in error state" - ); - - // Switch page back out of reader mode. - promisePageShow = BrowserTestUtils.waitForContentEvent( - newTab.linkedBrowser, - "pageshow", - false, - e => e.target.location.href != "about:blank" - ); - readerButton.click(); - await promisePageShow; - is( - gBrowser.selectedBrowser.currentURI.spec, - nonReadableUrl, - "Back to the original non-reader-able page after clicking active reader mode button" - ); - await TestUtils.waitForCondition(() => readerButton.hidden); - is_element_hidden( - readerButton, - "Reader mode button is not present on a non-reader-able page" - ); -}); - -add_task(async function test_getOriginalUrl() { - let { ReaderMode } = ChromeUtils.importESModule( - "resource://gre/modules/ReaderMode.sys.mjs" - ); - let url = "https://foo.com/article.html"; - - is( - ReaderMode.getOriginalUrl("about:reader?url=" + encodeURIComponent(url)), - url, - "Found original URL from encoded URL" - ); - is( - ReaderMode.getOriginalUrl("about:reader?foobar"), - null, - "Did not find original URL from malformed reader URL" - ); - is( - ReaderMode.getOriginalUrl(url), - null, - "Did not find original URL from non-reader URL" - ); - - let badUrl = "https://foo.com/?;$%^^"; - is( - ReaderMode.getOriginalUrl("about:reader?url=" + encodeURIComponent(badUrl)), - badUrl, - "Found original URL from encoded malformed URL" - ); - is( - ReaderMode.getOriginalUrl("about:reader?url=" + badUrl), - badUrl, - "Found original URL from non-encoded malformed URL" - ); -}); - -add_task(async function test_reader_view_element_attribute_transform() { - registerCleanupFunction(function () { - while (gBrowser.tabs.length > 1) { - gBrowser.removeCurrentTab(); - } - }); - - function observeAttribute(element, attributes, triggerFn, checkFn) { - return new Promise(resolve => { - let observer = new MutationObserver(mutations => { - for (let mu of mutations) { - if (element.getAttribute(mu.attributeName) !== mu.oldValue) { - if (checkFn()) { - resolve(); - observer.disconnect(); - return; - } - } - } - }); - - observer.observe(element, { - attributes: true, - attributeOldValue: true, - attributeFilter: Array.isArray(attributes) ? attributes : [attributes], - }); - - triggerFn(); - }); - } - - let menuitem = document.getElementById("menu_readerModeItem"); - let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser); - is( - menuitem.hidden, - true, - "menuitem element should have the hidden attribute" - ); - - info("Navigate a reader-able page"); - function waitForNonBlankPage() { - return BrowserTestUtils.waitForContentEvent( - tab.linkedBrowser, - "pageshow", - false, - e => e.target.location.href != "about:blank" - ); - } - let waitForPageshow = waitForNonBlankPage(); - await observeAttribute( - menuitem, - "hidden", - () => { - let url = TEST_PATH + "readerModeArticle.html"; - BrowserTestUtils.startLoadingURIString(tab.linkedBrowser, url); - }, - () => !menuitem.hidden - ); - is( - menuitem.hidden, - false, - "menuitem's hidden attribute should be false on a reader-able page" - ); - await waitForPageshow; - - info("Navigate a non-reader-able page"); - waitForPageshow = waitForNonBlankPage(); - await observeAttribute( - menuitem, - "hidden", - () => { - let url = TEST_PATH + "readerModeArticleHiddenNodes.html"; - BrowserTestUtils.startLoadingURIString(tab.linkedBrowser, url); - }, - () => menuitem.hidden - ); - is( - menuitem.hidden, - true, - "menuitem's hidden attribute should be true on a non-reader-able page" - ); - await waitForPageshow; - - info("Navigate a reader-able page"); - waitForPageshow = waitForNonBlankPage(); - await observeAttribute( - menuitem, - "hidden", - () => { - let url = TEST_PATH + "readerModeArticle.html"; - BrowserTestUtils.startLoadingURIString(tab.linkedBrowser, url); - }, - () => !menuitem.hidden - ); - is( - menuitem.hidden, - false, - "menuitem's hidden attribute should be false on a reader-able page" - ); - await waitForPageshow; - - info("Enter Reader Mode"); - waitForPageshow = waitForNonBlankPage(); - await observeAttribute( - readerButton, - "readeractive", - () => { - readerButton.click(); - }, - () => readerButton.getAttribute("readeractive") == "true" - ); - is( - readerButton.getAttribute("readeractive"), - "true", - "readerButton's readeractive attribute should be true when entering reader mode" - ); - await waitForPageshow; - - info("Exit Reader Mode"); - waitForPageshow = waitForNonBlankPage(); - await observeAttribute( - readerButton, - ["readeractive", "hidden"], - () => { - readerButton.click(); - }, - () => { - info( - `active: ${readerButton.getAttribute("readeractive")}; hidden: ${ - menuitem.hidden - }` - ); - return !readerButton.getAttribute("readeractive") && !menuitem.hidden; - } - ); - ok( - !readerButton.getAttribute("readeractive"), - "readerButton's readeractive attribute should be empty when reader mode is exited" - ); - ok(!menuitem.hidden, "menuitem should not be hidden."); - await waitForPageshow; - - info("Navigate a non-reader-able page"); - waitForPageshow = waitForNonBlankPage(); - await observeAttribute( - menuitem, - "hidden", - () => { - let url = TEST_PATH + "readerModeArticleHiddenNodes.html"; - BrowserTestUtils.startLoadingURIString(tab.linkedBrowser, url); - }, - () => menuitem.hidden - ); - is( - menuitem.hidden, - true, - "menuitem's hidden attribute should be true on a non-reader-able page" - ); - await waitForPageshow; -}); - -add_task(async function test_reader_mode_lang() { - let url = TEST_PATH + "readerModeArticle.html"; - let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser); - BrowserTestUtils.startLoadingURIString(tab.linkedBrowser, url); - - await promiseTabLoadEvent(tab, url); - await TestUtils.waitForCondition(() => !readerButton.hidden); - - // Switch page into reader mode. - let promiseTabLoad = promiseTabLoadEvent(tab); - readerButton.click(); - await promiseTabLoad; - - await SpecialPowers.spawn(gBrowser.selectedBrowser, [], () => { - let container = content.document.querySelector(".container"); - is(container.lang, "en"); - }); -}); diff --git a/toolkit/components/reader/test/browser_readerMode_bc_reuse.js b/toolkit/components/reader/test/browser_readerMode_bc_reuse.js deleted file mode 100644 index 9ac0e367ca..0000000000 --- a/toolkit/components/reader/test/browser_readerMode_bc_reuse.js +++ /dev/null @@ -1,44 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -"use strict"; - -const TEST_PATH = getRootDirectory(gTestPath).replace( - "chrome://mochitests/content", - "http://example.com" -); - -const TEST_URL = TEST_PATH + "readerModeArticle.html"; - -add_task(async function test_TODO() { - await BrowserTestUtils.withNewTab( - "data:text/html,

Opener", - async browser => { - let newTabPromise = BrowserTestUtils.waitForNewTab( - gBrowser, - TEST_URL, - true - ); - await SpecialPowers.spawn(browser, [TEST_URL], url => { - content.eval(`window.x = open("${url}", "_blank");`); - }); - let newTab = await newTabPromise; - - let readerButton = document.getElementById("reader-mode-button"); - await BrowserTestUtils.waitForMutationCondition( - readerButton, - { attributes: true }, - () => !readerButton.hidden - ); - let tabLoaded = promiseTabLoadEvent(newTab); - readerButton.click(); - await tabLoaded; - isnot( - newTab.linkedBrowser.browsingContext.group.id, - browser.browsingContext.group.id, - "BC should be in a different group now." - ); - BrowserTestUtils.removeTab(newTab); - } - ); -}); diff --git a/toolkit/components/reader/test/browser_readerMode_cached.js b/toolkit/components/reader/test/browser_readerMode_cached.js deleted file mode 100644 index 7f36a15dbb..0000000000 --- a/toolkit/components/reader/test/browser_readerMode_cached.js +++ /dev/null @@ -1,32 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ -"use strict"; - -// This test verifies that the article is properly using the cached data -// when switching into reader mode. The article produces a random number -// contained within it, so if the article gets reloaded instead of using -// the cached version, it would have a different value in it. -const URL = - "http://mochi.test:8888/browser/toolkit/components/reader/test/readerModeRandom.sjs"; - -add_task(async function () { - let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, URL); - - let randomNumber = await SpecialPowers.spawn(tab.linkedBrowser, [], () => { - return content.document.getElementById("rnd").textContent; - }); - - let promiseTabLoad = promiseTabLoadEvent(tab); - let readerButton = document.getElementById("reader-mode-button"); - readerButton.click(); - await promiseTabLoad; - await TestUtils.waitForCondition(() => !readerButton.hidden); - - let newRandomNumber = await SpecialPowers.spawn(tab.linkedBrowser, [], () => { - return content.document.getElementById("rnd").textContent; - }); - - is(randomNumber, newRandomNumber, "used the same value"); - - BrowserTestUtils.removeTab(tab); -}); diff --git a/toolkit/components/reader/test/browser_readerMode_colorSchemePref.js b/toolkit/components/reader/test/browser_readerMode_colorSchemePref.js deleted file mode 100644 index 0bee6eaf05..0000000000 --- a/toolkit/components/reader/test/browser_readerMode_colorSchemePref.js +++ /dev/null @@ -1,67 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -const TEST_PATH = getRootDirectory(gTestPath).replace( - "chrome://mochitests/content", - "http://example.com" -); - -async function testColorScheme(aPref, aExpectation) { - // Set the browser content theme to light or dark. - Services.prefs.setIntPref("browser.theme.content-theme", aPref); - - // Reader Mode Color Scheme Preference must be manually set by the user, will - // default to "auto" initially. - Services.prefs.setCharPref("reader.color_scheme", aExpectation); - - let aBodyExpectation = aExpectation; - if (aBodyExpectation === "auto") { - aBodyExpectation = aPref === 1 ? "light" : "dark"; - } - - // Open a browser tab, enter reader mode, and test if we have the valid - // reader mode color scheme preference pre-selected. - await BrowserTestUtils.withNewTab( - TEST_PATH + "readerModeArticle.html", - async function (browser) { - let pageShownPromise = BrowserTestUtils.waitForContentEvent( - browser, - "AboutReaderContentReady" - ); - - let readerButton = document.getElementById("reader-mode-button"); - readerButton.click(); - await pageShownPromise; - - let colorScheme = Services.prefs.getCharPref("reader.color_scheme"); - - Assert.equal(colorScheme, aExpectation); - - await SpecialPowers.spawn(browser, [aBodyExpectation], expectation => { - let bodyClass = content.document.body.className; - ok( - bodyClass.includes(expectation), - "The body of the test document has the correct color scheme." - ); - }); - } - ); -} - -/** - * Test that opening reader mode maintains the correct color scheme preference - * until the user manually sets a different color scheme. - */ -add_task(async function () { - await testColorScheme(0, "auto"); - await testColorScheme(1, "auto"); - await testColorScheme(0, "light"); - await testColorScheme(1, "light"); - await testColorScheme(0, "dark"); - await testColorScheme(1, "dark"); - await testColorScheme(0, "sepia"); - await testColorScheme(1, "sepia"); -}); diff --git a/toolkit/components/reader/test/browser_readerMode_hidden_nodes.js b/toolkit/components/reader/test/browser_readerMode_hidden_nodes.js deleted file mode 100644 index d8e432a164..0000000000 --- a/toolkit/components/reader/test/browser_readerMode_hidden_nodes.js +++ /dev/null @@ -1,56 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/** - * Test that the reader mode button appears and works properly on - * reader-able content. - */ -const TEST_PREFS = [["reader.parse-on-load.enabled", true]]; - -const TEST_PATH = getRootDirectory(gTestPath).replace( - "chrome://mochitests/content", - "http://example.com" -); - -var readerButton = document.getElementById("reader-mode-button"); - -add_task(async function test_reader_button() { - registerCleanupFunction(function () { - // Reset test prefs. - TEST_PREFS.forEach(([name, value]) => { - Services.prefs.clearUserPref(name); - }); - while (gBrowser.tabs.length > 1) { - gBrowser.removeCurrentTab(); - } - }); - - // Set required test prefs. - TEST_PREFS.forEach(([name, value]) => { - Services.prefs.setBoolPref(name, value); - }); - - let tab = (gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser)); - is_element_hidden( - readerButton, - "Reader mode button is not present on a new tab" - ); - // Point tab to a test page that is not reader-able due to hidden nodes. - let url = TEST_PATH + "readerModeArticleHiddenNodes.html"; - let paintPromise = BrowserTestUtils.waitForContentEvent( - tab.linkedBrowser, - "MozAfterPaint", - false, - e => - e.originalTarget.location.href.endsWith("HiddenNodes.html") && - e.originalTarget.document.readyState == "complete" - ); - BrowserTestUtils.startLoadingURIString(tab.linkedBrowser, url); - await paintPromise; - - is_element_hidden( - readerButton, - "Reader mode button is still not present on tab with unreadable content." - ); -}); diff --git a/toolkit/components/reader/test/browser_readerMode_menu.js b/toolkit/components/reader/test/browser_readerMode_menu.js deleted file mode 100644 index 304fefa5d0..0000000000 --- a/toolkit/components/reader/test/browser_readerMode_menu.js +++ /dev/null @@ -1,69 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -const TEST_PATH = getRootDirectory(gTestPath).replace( - "chrome://mochitests/content", - "http://example.com" -); - -/** - * Test that the reader mode correctly calculates and displays the - * estimated reading time for a short article - */ -add_task(async function () { - await BrowserTestUtils.withNewTab( - TEST_PATH + "readerModeArticleShort.html", - async function (browser) { - let pageShownPromise = BrowserTestUtils.waitForContentEvent( - browser, - "AboutReaderContentReady" - ); - let readerButton = document.getElementById("reader-mode-button"); - readerButton.click(); - await pageShownPromise; - await SpecialPowers.spawn(browser, [], async function () { - function dispatchMouseEvent(win, target, eventName) { - let mouseEvent = new win.MouseEvent(eventName, { - view: win, - bubbles: true, - cancelable: true, - composed: true, - }); - target.dispatchEvent(mouseEvent); - } - - function simulateClick(target) { - dispatchMouseEvent(win, target, "mousedown"); - dispatchMouseEvent(win, target, "mouseup"); - dispatchMouseEvent(win, target, "click"); - } - - let doc = content.document; - let win = content.window; - let styleButton = doc.querySelector(".style-button"); - - let styleDropdown = doc.querySelector(".style-dropdown"); - ok(!styleDropdown.classList.contains("open"), "dropdown is closed"); - - simulateClick(styleButton); - ok(styleDropdown.classList.contains("open"), "dropdown is open"); - - // simulate clicking on the article title to close the dropdown - let title = doc.querySelector("h1"); - simulateClick(title); - ok(!styleDropdown.classList.contains("open"), "dropdown is closed"); - - // reopen the dropdown - simulateClick(styleButton); - ok(styleDropdown.classList.contains("open"), "dropdown is open"); - - // now click on the button again to close it - simulateClick(styleButton); - ok(!styleDropdown.classList.contains("open"), "dropdown is closed"); - }); - } - ); -}); diff --git a/toolkit/components/reader/test/browser_readerMode_pocket.js b/toolkit/components/reader/test/browser_readerMode_pocket.js deleted file mode 100644 index 43426383ff..0000000000 --- a/toolkit/components/reader/test/browser_readerMode_pocket.js +++ /dev/null @@ -1,136 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ -"use strict"; - -// This test verifies that the Save To Pocket button appears in reader mode, -// and is toggled hidden and visible when pocket is disabled and enabled. - -const TEST_PATH = getRootDirectory(gTestPath).replace( - "chrome://mochitests/content", - "http://example.com" -); - -async function getPocketButtonsCount(browser) { - return SpecialPowers.spawn(browser, [], () => { - return content.document.getElementsByClassName("pocket-button").length; - }); -} - -add_task(async function () { - // set the pocket preference before beginning. - await SpecialPowers.pushPrefEnv({ - set: [["extensions.pocket.enabled", true]], - }); - - var readerButton = document.getElementById("reader-mode-button"); - - let tab1 = await BrowserTestUtils.openNewForegroundTab( - gBrowser, - TEST_PATH + "readerModeArticleShort.html" - ); - - let promiseTabLoad = promiseTabLoadEvent(tab1); - readerButton.click(); - await promiseTabLoad; - - let tab2 = await BrowserTestUtils.openNewForegroundTab( - gBrowser, - TEST_PATH + "readerModeArticleMedium.html" - ); - - promiseTabLoad = promiseTabLoadEvent(tab2); - readerButton.click(); - await promiseTabLoad; - - is( - await getPocketButtonsCount(tab1.linkedBrowser), - 1, - "tab 1 has a pocket button" - ); - is( - await getPocketButtonsCount(tab1.linkedBrowser), - 1, - "tab 2 has a pocket button" - ); - - // Turn off the pocket preference. The Save To Pocket buttons should disappear. - await SpecialPowers.pushPrefEnv({ - set: [["extensions.pocket.enabled", false]], - }); - - is( - await getPocketButtonsCount(tab1.linkedBrowser), - 0, - "tab 1 has no pocket button" - ); - is( - await getPocketButtonsCount(tab1.linkedBrowser), - 0, - "tab 2 has no pocket button" - ); - - // Turn on the pocket preference. The Save To Pocket buttons should reappear again. - await SpecialPowers.pushPrefEnv({ - set: [["extensions.pocket.enabled", true]], - }); - - is( - await getPocketButtonsCount(tab1.linkedBrowser), - 1, - "tab 1 has a pocket button again" - ); - is( - await getPocketButtonsCount(tab1.linkedBrowser), - 1, - "tab 2 has a pocket button again" - ); - - BrowserTestUtils.removeTab(tab1); - BrowserTestUtils.removeTab(tab2); -}); - -/** - * Test that the pocket button toggles the pocket popup successfully - */ -add_task(async function () { - await BrowserTestUtils.withNewTab( - TEST_PATH + "readerModeArticleShort.html", - async function (browser) { - let pageShownPromise = BrowserTestUtils.waitForContentEvent( - browser, - "AboutReaderContentReady" - ); - let readerButton = document.getElementById("reader-mode-button"); - readerButton.click(); - await pageShownPromise; - - await SpecialPowers.spawn(browser, [], async function () { - content.document.querySelector(".pocket-button").click(); - }); - let panel = gBrowser.selectedBrowser.ownerDocument.querySelector( - "#customizationui-widget-panel" - ); - await BrowserTestUtils.waitForMutationCondition( - panel, - { attributes: true }, - () => { - return BrowserTestUtils.isVisible(panel); - } - ); - ok(BrowserTestUtils.isVisible(panel), "Panel buttons are visible"); - - await SpecialPowers.spawn(browser, [], async function () { - content.document.querySelector(".pocket-button").click(); - }); - await BrowserTestUtils.waitForMutationCondition( - panel, - { attributes: true }, - () => { - return BrowserTestUtils.isHidden(panel); - } - ); - - ok(BrowserTestUtils.isHidden(panel), "Panel buttons are hidden"); - } - ); -}); diff --git a/toolkit/components/reader/test/browser_readerMode_readingTime.js b/toolkit/components/reader/test/browser_readerMode_readingTime.js deleted file mode 100644 index 91631b6234..0000000000 --- a/toolkit/components/reader/test/browser_readerMode_readingTime.js +++ /dev/null @@ -1,101 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -const TEST_PATH = getRootDirectory(gTestPath).replace( - "chrome://mochitests/content", - "http://example.com" -); - -/** - * Test that the reader mode correctly calculates and displays the - * estimated reading time for a normal length article - */ -add_task(async function () { - await BrowserTestUtils.withNewTab( - TEST_PATH + "readerModeArticle.html", - async function (browser) { - let pageShownPromise = BrowserTestUtils.waitForContentEvent( - browser, - "AboutReaderContentReady" - ); - let readerButton = document.getElementById("reader-mode-button"); - readerButton.click(); - await pageShownPromise; - await SpecialPowers.spawn(browser, [], async function () { - // make sure there is a reading time on the page and that it displays the correct information - let readingTimeElement = content.document.querySelector( - ".reader-estimated-time" - ); - ok(readingTimeElement, "Reading time element should be in document"); - const args = JSON.parse(readingTimeElement.dataset.l10nArgs); - is(args.rangePlural, "other", "Reading time should be '9-12 minutes'"); - ok( - /\b9\b.*\b12\b/.test(args.range), - "Reading time should be '9-12 minutes'" - ); - }); - } - ); -}); - -/** - * Test that the reader mode correctly calculates and displays the - * estimated reading time for a short article - */ -add_task(async function () { - await BrowserTestUtils.withNewTab( - TEST_PATH + "readerModeArticleShort.html", - async function (browser) { - let pageShownPromise = BrowserTestUtils.waitForContentEvent( - browser, - "AboutReaderContentReady" - ); - let readerButton = document.getElementById("reader-mode-button"); - readerButton.click(); - await pageShownPromise; - await SpecialPowers.spawn(browser, [], async function () { - // make sure there is a reading time on the page and that it displays the correct information - let readingTimeElement = content.document.querySelector( - ".reader-estimated-time" - ); - ok(readingTimeElement, "Reading time element should be in document"); - const args = JSON.parse(readingTimeElement.dataset.l10nArgs); - is(args.rangePlural, "one", "Reading time should be '~1 minute'"); - ok(/\b1\b/.test(args.range), "Reading time should be '~1 minute'"); - }); - } - ); -}); - -/** - * Test that the reader mode correctly calculates and displays the - * estimated reading time for a medium article where a single number - * is displayed. - */ -add_task(async function () { - await BrowserTestUtils.withNewTab( - TEST_PATH + "readerModeArticleMedium.html", - async function (browser) { - let pageShownPromise = BrowserTestUtils.waitForContentEvent( - browser, - "AboutReaderContentReady" - ); - let readerButton = document.getElementById("reader-mode-button"); - readerButton.click(); - await pageShownPromise; - await SpecialPowers.spawn(browser, [], async function () { - // make sure there is a reading time on the page and that it displays the correct information - let readingTimeElement = content.document.querySelector( - ".reader-estimated-time" - ); - ok(readingTimeElement, "Reading time element should be in document"); - const args = JSON.parse(readingTimeElement.dataset.l10nArgs); - is(args.rangePlural, "other", "Reading time should be '~3 minutes'"); - ok(/\b3\b/.test(args.range), "Reading time should be '~3 minutes'"); - }); - } - ); -}); diff --git a/toolkit/components/reader/test/browser_readerMode_refresh.js b/toolkit/components/reader/test/browser_readerMode_refresh.js deleted file mode 100644 index 00b4557f70..0000000000 --- a/toolkit/components/reader/test/browser_readerMode_refresh.js +++ /dev/null @@ -1,49 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -const TEST_PATH = getRootDirectory(gTestPath).replace( - "chrome://mochitests/content", - "http://example.com" -); - -async function testRefresh(url) { - // Open an article in a browser tab - await BrowserTestUtils.withNewTab(url, async function (browser) { - let pageShownPromise = BrowserTestUtils.waitForContentEvent( - browser, - "AboutReaderContentReady" - ); - - let readerButton = document.getElementById("reader-mode-button"); - let refreshButton = document.getElementById("reload-button"); - - // Enter Reader Mode - readerButton.click(); - await pageShownPromise; - - // Refresh the page - pageShownPromise = BrowserTestUtils.waitForContentEvent( - browser, - "AboutReaderContentReady" - ); - refreshButton.click(); - await pageShownPromise; - await SpecialPowers.spawn(browser, [], () => { - ok( - !content.document.documentElement.hasAttribute("data-is-error"), - "The data-is-error attribute is present when Reader Mode failed to load an article." - ); - }); - }); -} - -add_task(async function () { - // Testing a non-text/plain document - await testRefresh(TEST_PATH + "readerModeArticle.html"); - - // Testing a test/plain document - await testRefresh(TEST_PATH + "readerModeArticleTextPlain.txt"); -}); diff --git a/toolkit/components/reader/test/browser_readerMode_remoteType.js b/toolkit/components/reader/test/browser_readerMode_remoteType.js deleted file mode 100644 index c2510667c8..0000000000 --- a/toolkit/components/reader/test/browser_readerMode_remoteType.js +++ /dev/null @@ -1,87 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -const TEST_PATH = getRootDirectory(gTestPath).replace( - "chrome://mochitests/content", - "http://example.com" -); - -const CROSS_SITE_TEST_PATH = getRootDirectory(gTestPath).replace( - "chrome://mochitests/content", - "http://example.org" -); - -/** - * Test that switching an article into readermode doesn't change its' remoteType. - * Test that the reader mode correctly calculates and displays the - * estimated reading time for a short article - */ -add_task(async function () { - info("opening readermode normally to ensure process doesn't change"); - let articleRemoteType; - let aboutReaderURL; - await BrowserTestUtils.withNewTab( - TEST_PATH + "readerModeArticleShort.html", - async function (browser) { - articleRemoteType = browser.remoteType; - - // Click on the readermode button to switch into reader mode, and get the - // URL for that reader mode. - let pageShownPromise = BrowserTestUtils.waitForContentEvent( - browser, - "AboutReaderContentReady" - ); - let readerButton = document.getElementById("reader-mode-button"); - readerButton.click(); - await pageShownPromise; - - aboutReaderURL = browser.documentURI.spec; - ok( - aboutReaderURL.startsWith("about:reader"), - "about:reader should have been opened" - ); - is( - browser.remoteType, - articleRemoteType, - "remote type should not have changed" - ); - } - ); - - info( - "opening new tab directly with about reader URL into correct remote type" - ); - await BrowserTestUtils.withNewTab(aboutReaderURL, async function (browser) { - is( - browser.remoteType, - articleRemoteType, - "Should have performed about:reader load in the correct remote type" - ); - }); - - info("navigating process into correct remote type"); - await BrowserTestUtils.withNewTab( - CROSS_SITE_TEST_PATH + "readerModeArticleShort.html", - async function (browser) { - if (SpecialPowers.useRemoteSubframes) { - isnot( - browser.remoteType, - articleRemoteType, - "Cross-site article should have different remote type with fission" - ); - } - - BrowserTestUtils.startLoadingURIString(browser, aboutReaderURL); - await BrowserTestUtils.browserLoaded(browser); - - is( - browser.remoteType, - articleRemoteType, - "Should have switched into the correct remote type" - ); - } - ); -}); diff --git a/toolkit/components/reader/test/browser_readerMode_samesite_cookie_redirect.js b/toolkit/components/reader/test/browser_readerMode_samesite_cookie_redirect.js deleted file mode 100644 index 22703b9a81..0000000000 --- a/toolkit/components/reader/test/browser_readerMode_samesite_cookie_redirect.js +++ /dev/null @@ -1,52 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -"use strict"; - -const TEST_ORIGIN = getRootDirectory(gTestPath).replace( - "chrome://mochitests/content", - "http://example.com" -); - -const { HttpServer } = ChromeUtils.importESModule( - "resource://testing-common/httpd.sys.mjs" -); - -add_task(async function test_ss_cookie_redirect() { - // Set the samesite cookie - let tab = await BrowserTestUtils.openNewForegroundTab( - gBrowser, - TEST_ORIGIN + "setSameSiteCookie.html" - ); - BrowserTestUtils.removeTab(tab); - - let server = new HttpServer(); - server.start(-1); - server.registerPathHandler("/foo", (request, response) => { - response.setStatusLine(request.httpVersion, 302, "Found"); - response.setHeader("Location", TEST_ORIGIN + "getCookies.sjs"); - }); - registerCleanupFunction(() => server.stop()); - const { primaryPort, primaryHost } = server.identity; - const serverURL = `http://${primaryHost}:${primaryPort}/foo`; - - // Now open `getCookies.sjs` but via a redirect: - await BrowserTestUtils.withNewTab("about:blank", async browser => { - let loaded = BrowserTestUtils.waitForContentEvent( - browser, - "AboutReaderContentReady" - ); - BrowserTestUtils.startLoadingURIString( - browser, - "about:reader?url=" + encodeURIComponent(serverURL) - ); - await loaded; - await SpecialPowers.spawn(browser, [], () => { - is( - content.document.getElementById("cookieSpan").textContent, - "", - "Shouldn't get cookies." - ); - }); - }); -}); diff --git a/toolkit/components/reader/test/browser_readerMode_with_anchor.js b/toolkit/components/reader/test/browser_readerMode_with_anchor.js deleted file mode 100644 index 229daaed9d..0000000000 --- a/toolkit/components/reader/test/browser_readerMode_with_anchor.js +++ /dev/null @@ -1,89 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -const TEST_PATH = getRootDirectory(gTestPath).replace( - "chrome://mochitests/content", - "http://example.com" -); - -add_task(async function test_loading_withHash() { - await BrowserTestUtils.withNewTab( - TEST_PATH + "readerModeArticle.html#foo", - async function (browser) { - let pageShownPromise = BrowserTestUtils.waitForContentEvent( - browser, - "AboutReaderContentReady" - ); - let readerButton = document.getElementById("reader-mode-button"); - readerButton.click(); - await pageShownPromise; - await SpecialPowers.spawn(browser, [], async function () { - let foo = content.document.getElementById("foo"); - ok(foo, "foo element should be in document"); - let { scrollTop } = content.document.documentElement; - if (scrollTop == 0) { - await ContentTaskUtils.waitForEvent(content.document, "scroll"); - ({ scrollTop } = content.document.documentElement); - } - let { offsetTop } = foo; - Assert.lessOrEqual( - Math.abs(scrollTop - offsetTop), - 1, - `scrollTop (${scrollTop}) should be within 1 CSS pixel of offsetTop (${offsetTop})` - ); - }); - } - ); -}); - -add_task(async function test_loading_withoutHash() { - await BrowserTestUtils.withNewTab( - TEST_PATH + "readerModeArticle.html", - async function (browser) { - let pageShownPromise = BrowserTestUtils.waitForContentEvent( - browser, - "AboutReaderContentReady" - ); - let pageLoadedPromise = BrowserTestUtils.waitForContentEvent( - browser, - "load", - true - ); - let readerButton = document.getElementById("reader-mode-button"); - readerButton.click(); - await Promise.all([pageShownPromise, pageLoadedPromise]); - await SpecialPowers.spawn(gBrowser.selectedBrowser, [], async () => { - Assert.equal( - content.document.documentElement.scrollTop, - 0, - "scrollTop should be 0" - ); - }); - let scrollEventPromise = BrowserTestUtils.waitForContentEvent( - browser, - "scroll", - true - ); - await BrowserTestUtils.synthesizeMouseAtCenter( - "#foo-anchor", - {}, - browser - ); - await scrollEventPromise; - await SpecialPowers.spawn(browser, [], async function () { - let foo = content.document.getElementById("foo"); - ok(foo, "foo element should be in document"); - let { scrollTop } = content.document.documentElement; - let { offsetTop } = foo; - Assert.lessOrEqual( - Math.abs(scrollTop - offsetTop), - 1, - `scrollTop (${scrollTop}) should be within 1 CSS pixel of offsetTop (${offsetTop})` - ); - }); - } - ); -}); diff --git a/toolkit/components/reader/test/getCookies.sjs b/toolkit/components/reader/test/getCookies.sjs deleted file mode 100644 index 02e29fd877..0000000000 --- a/toolkit/components/reader/test/getCookies.sjs +++ /dev/null @@ -1,16 +0,0 @@ -function handleRequest(request, response) { - const cookies = request.hasHeader("Cookie") - ? request.getHeader("Cookie") - : ""; - response.write(` - - - - - - -

Cookie: ${cookies}

- - - `); -} diff --git a/toolkit/components/reader/test/head.js b/toolkit/components/reader/test/head.js deleted file mode 100644 index 5f9baf8fcd..0000000000 --- a/toolkit/components/reader/test/head.js +++ /dev/null @@ -1,59 +0,0 @@ -/* exported promiseTabLoadEvent, is_element_visible, is_element_hidden */ - -/** - * Waits for a load (or custom) event to finish in a given tab. If provided - * load an uri into the tab. - * - * @param tab - * The tab to load into. - * @param [optional] url - * The url to load, or the current url. - * @return {Promise} resolved when the event is handled. - * @resolves to the received event - * @rejects if a valid load event is not received within a meaningful interval - */ -function promiseTabLoadEvent(tab, url) { - let deferred = Promise.withResolvers(); - info("Wait tab event: load"); - - function handle(loadedUrl) { - if (loadedUrl === "about:blank" || (url && loadedUrl !== url)) { - info(`Skipping spurious load event for ${loadedUrl}`); - return false; - } - - info("Tab event received: load"); - return true; - } - - // Create two promises: one resolved from the content process when the page - // loads and one that is rejected if we take too long to load the url. - let loaded = BrowserTestUtils.browserLoaded(tab.linkedBrowser, false, handle); - - let timeout = setTimeout(() => { - deferred.reject(new Error("Timed out while waiting for a 'load' event")); - }, 30000); - - loaded.then(() => { - clearTimeout(timeout); - deferred.resolve(); - }); - - if (url) { - BrowserTestUtils.startLoadingURIString(tab.linkedBrowser, url); - } - - // Promise.all rejects if either promise rejects (i.e. if we time out) and - // if our loaded promise resolves before the timeout, then we resolve the - // timeout promise as well, causing the all promise to resolve. - return Promise.all([deferred.promise, loaded]); -} - -function is_element_visible(element, msg) { - isnot(element, null, "Element should not be null, when checking visibility"); - ok(BrowserTestUtils.isVisible(element), msg || "Element should be visible"); -} -function is_element_hidden(element, msg) { - isnot(element, null, "Element should not be null, when checking visibility"); - ok(BrowserTestUtils.isHidden(element), msg || "Element should be hidden"); -} diff --git a/toolkit/components/reader/test/linkToGetCookies.html b/toolkit/components/reader/test/linkToGetCookies.html deleted file mode 100644 index 341046a21d..0000000000 --- a/toolkit/components/reader/test/linkToGetCookies.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - -
-

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ut gravida lorem. Ut turpis felis, pulvinar a semper sed, adipiscing id dolor. Pellentesque auctor nisi id magna consequat sagittis. Curabitur dapibus enim sit amet elit pharetra tincidunt feugiat nisl imperdiet. Ut convallis libero in urna ultrices accumsan. Donec sed odio eros. Donec viverra mi quis quam pulvinar at malesuada arcu rhoncus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In rutrum accumsan ultricies. Mauris vitae nisi at sem facilisis semper ac in est.

- -

Cross-origin link to getCookies.html

-
- - diff --git a/toolkit/components/reader/test/readerModeArticle.html b/toolkit/components/reader/test/readerModeArticle.html deleted file mode 100644 index a0f1c64da0..0000000000 --- a/toolkit/components/reader/test/readerModeArticle.html +++ /dev/null @@ -1,28 +0,0 @@ - - - -Article title - - - -
Site header
-
-

Article title

- -

by Jane Doe

-

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ut gravida lorem. Ut turpis felis, pulvinar a semper sed, adipiscing id dolor. Pellentesque auctor nisi id magna consequat sagittis. Curabitur dapibus enim sit amet elit pharetra tincidunt feugiat nisl imperdiet. Ut convallis libero in urna ultrices accumsan. Donec sed odio eros. Donec viverra mi quis quam pulvinar at malesuada arcu rhoncus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In rutrum accumsan ultricies. Mauris vitae nisi at sem facilisis semper ac in est.

-

Vivamus fermentum semper porta. Nunc diam velit, adipiscing ut tristique vitae, sagittis vel odio. Maecenas convallis ullamcorper ultricies. Curabitur ornare, ligula semper consectetur sagittis, nisi diam iaculis velit, id fringilla sem nunc vel mi. Nam dictum, odio nec pretium volutpat, arcu ante placerat erat, non tristique elit urna et turpis. Quisque mi metus, ornare sit amet fermentum et, tincidunt et orci. Fusce eget orci a orci congue vestibulum. Ut dolor diam, elementum et vestibulum eu, porttitor vel elit. Curabitur venenatis pulvinar tellus gravida ornare. Sed et erat faucibus nunc euismod ultricies ut id justo. Nullam cursus suscipit nisi, et ultrices justo sodales nec. Fusce venenatis facilisis lectus ac semper. Aliquam at massa ipsum. Quisque bibendum purus convallis nulla ultrices ultricies. Nullam aliquam, mi eu aliquam tincidunt, purus velit laoreet tortor, viverra pretium nisi quam vitae mi. Fusce vel volutpat elit. Nam sagittis nisi dui.

-

Vivamus fermentum semper porta. Nunc diam velit, adipiscing ut tristique vitae, sagittis vel odio. Maecenas convallis ullamcorper ultricies. Curabitur ornare, ligula semper consectetur sagittis, nisi diam iaculis velit, id fringilla sem nunc vel mi. Nam dictum, odio nec pretium volutpat, arcu ante placerat erat, non tristique elit urna et turpis. Quisque mi metus, ornare sit amet fermentum et, tincidunt et orci. Fusce eget orci a orci congue vestibulum. Ut dolor diam, elementum et vestibulum eu, porttitor vel elit. Curabitur venenatis pulvinar tellus gravida ornare. Sed et erat faucibus nunc euismod ultricies ut id justo. Nullam cursus suscipit nisi, et ultrices justo sodales nec. Fusce venenatis facilisis lectus ac semper. Aliquam at massa ipsum. Quisque bibendum purus convallis nulla ultrices ultricies. Nullam aliquam, mi eu aliquam tincidunt, purus velit laoreet tortor, viverra pretium nisi quam vitae mi. Fusce vel volutpat elit. Nam sagittis nisi dui.

-

Vivamus fermentum semper porta. Nunc diam velit, adipiscing ut tristique vitae, sagittis vel odio. Maecenas convallis ullamcorper ultricies. Curabitur ornare, ligula semper consectetur sagittis, nisi diam iaculis velit, id fringilla sem nunc vel mi. Nam dictum, odio nec pretium volutpat, arcu ante placerat erat, non tristique elit urna et turpis. Quisque mi metus, ornare sit amet fermentum et, tincidunt et orci. Fusce eget orci a orci congue vestibulum. Ut dolor diam, elementum et vestibulum eu, porttitor vel elit. Curabitur venenatis pulvinar tellus gravida ornare. Sed et erat faucibus nunc euismod ultricies ut id justo. Nullam cursus suscipit nisi, et ultrices justo sodales nec. Fusce venenatis facilisis lectus ac semper. Aliquam at massa ipsum. Quisque bibendum purus convallis nulla ultrices ultricies. Nullam aliquam, mi eu aliquam tincidunt, purus velit laoreet tortor, viverra pretium nisi quam vitae mi. Fusce vel volutpat elit. Nam sagittis nisi dui.

-

Vivamus fermentum semper porta. Nunc diam velit, adipiscing ut tristique vitae, sagittis vel odio. Maecenas convallis ullamcorper ultricies. Curabitur ornare, ligula semper consectetur sagittis, nisi diam iaculis velit, id fringilla sem nunc vel mi. Nam dictum, odio nec pretium volutpat, arcu ante placerat erat, non tristique elit urna et turpis. Quisque mi metus, ornare sit amet fermentum et, tincidunt et orci. Fusce eget orci a orci congue vestibulum. Ut dolor diam, elementum et vestibulum eu, porttitor vel elit. Curabitur venenatis pulvinar tellus gravida ornare. Sed et erat faucibus nunc euismod ultricies ut id justo. Nullam cursus suscipit nisi, et ultrices justo sodales nec. Fusce venenatis facilisis lectus ac semper. Aliquam at massa ipsum. Quisque bibendum purus convallis nulla ultrices ultricies. Nullam aliquam, mi eu aliquam tincidunt, purus velit laoreet tortor, viverra pretium nisi quam vitae mi. Fusce vel volutpat elit. Nam sagittis nisi dui.

-

by John Doe

-

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ut gravida lorem. Ut turpis felis, pulvinar a semper sed, adipiscing id dolor. Pellentesque auctor nisi id magna consequat sagittis. Curabitur dapibus enim sit amet elit pharetra tincidunt feugiat nisl imperdiet. Ut convallis libero in urna ultrices accumsan. Donec sed odio eros. Donec viverra mi quis quam pulvinar at malesuada arcu rhoncus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In rutrum accumsan ultricies. Mauris vitae nisi at sem facilisis semper ac in est.

-

Vivamus fermentum semper porta. Nunc diam velit, adipiscing ut tristique vitae, sagittis vel odio. Maecenas convallis ullamcorper ultricies. Curabitur ornare, ligula semper consectetur sagittis, nisi diam iaculis velit, id fringilla sem nunc vel mi. Nam dictum, odio nec pretium volutpat, arcu ante placerat erat, non tristique elit urna et turpis. Quisque mi metus, ornare sit amet fermentum et, tincidunt et orci. Fusce eget orci a orci congue vestibulum. Ut dolor diam, elementum et vestibulum eu, porttitor vel elit. Curabitur venenatis pulvinar tellus gravida ornare. Sed et erat faucibus nunc euismod ultricies ut id justo. Nullam cursus suscipit nisi, et ultrices justo sodales nec. Fusce venenatis facilisis lectus ac semper. Aliquam at massa ipsum. Quisque bibendum purus convallis nulla ultrices ultricies. Nullam aliquam, mi eu aliquam tincidunt, purus velit laoreet tortor, viverra pretium nisi quam vitae mi. Fusce vel volutpat elit. Nam sagittis nisi dui.

-

Vivamus fermentum semper porta. Nunc diam velit, adipiscing ut tristique vitae, sagittis vel odio. Maecenas convallis ullamcorper ultricies. Curabitur ornare, ligula semper consectetur sagittis, nisi diam iaculis velit, id fringilla sem nunc vel mi. Nam dictum, odio nec pretium volutpat, arcu ante placerat erat, non tristique elit urna et turpis. Quisque mi metus, ornare sit amet fermentum et, tincidunt et orci. Fusce eget orci a orci congue vestibulum. Ut dolor diam, elementum et vestibulum eu, porttitor vel elit. Curabitur venenatis pulvinar tellus gravida ornare. Sed et erat faucibus nunc euismod ultricies ut id justo. Nullam cursus suscipit nisi, et ultrices justo sodales nec. Fusce venenatis facilisis lectus ac semper. Aliquam at massa ipsum. Quisque bibendum purus convallis nulla ultrices ultricies. Nullam aliquam, mi eu aliquam tincidunt, purus velit laoreet tortor, viverra pretium nisi quam vitae mi. Fusce vel volutpat elit. Nam sagittis nisi dui.

-

Vivamus fermentum semper porta. Nunc diam velit, adipiscing ut tristique vitae, sagittis vel odio. Maecenas convallis ullamcorper ultricies. Curabitur ornare, ligula semper consectetur sagittis, nisi diam iaculis velit, id fringilla sem nunc vel mi. Nam dictum, odio nec pretium volutpat, arcu ante placerat erat, non tristique elit urna et turpis. Quisque mi metus, ornare sit amet fermentum et, tincidunt et orci. Fusce eget orci a orci congue vestibulum. Ut dolor diam, elementum et vestibulum eu, porttitor vel elit. Curabitur venenatis pulvinar tellus gravida ornare. Sed et erat faucibus nunc euismod ultricies ut id justo. Nullam cursus suscipit nisi, et ultrices justo sodales nec. Fusce venenatis facilisis lectus ac semper. Aliquam at massa ipsum. Quisque bibendum purus convallis nulla ultrices ultricies. Nullam aliquam, mi eu aliquam tincidunt, purus velit laoreet tortor, viverra pretium nisi quam vitae mi. Fusce vel volutpat elit. Nam sagittis nisi dui.

-

Vivamus fermentum semper porta. Nunc diam velit, adipiscing ut tristique vitae, sagittis vel odio. Maecenas convallis ullamcorper ultricies. Curabitur ornare, ligula semper consectetur sagittis, nisi diam iaculis velit, id fringilla sem nunc vel mi. Nam dictum, odio nec pretium volutpat, arcu ante placerat erat, non tristique elit urna et turpis. Quisque mi metus, ornare sit amet fermentum et, tincidunt et orci. Fusce eget orci a orci congue vestibulum. Ut dolor diam, elementum et vestibulum eu, porttitor vel elit. Curabitur venenatis pulvinar tellus gravida ornare. Sed et erat faucibus nunc euismod ultricies ut id justo. Nullam cursus suscipit nisi, et ultrices justo sodales nec. Fusce venenatis facilisis lectus ac semper. Aliquam at massa ipsum. Quisque bibendum purus convallis nulla ultrices ultricies. Nullam aliquam, mi eu aliquam tincidunt, purus velit laoreet tortor, viverra pretium nisi quam vitae mi. Fusce vel volutpat elit. Nam sagittis nisi dui.

-
- - diff --git a/toolkit/components/reader/test/readerModeArticleContainsLink.html b/toolkit/components/reader/test/readerModeArticleContainsLink.html deleted file mode 100644 index 871349adcd..0000000000 --- a/toolkit/components/reader/test/readerModeArticleContainsLink.html +++ /dev/null @@ -1,20 +0,0 @@ - - - -Article title - - - -
Site header
-
-

Article title

-

by Jane Doe

-

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ut gravida lorem. Ut turpis felis, pulvinar a semper sed, adipiscing id dolor. Pellentesque auctor nisi id magna consequat sagittis. Curabitur dapibus enim sit amet elit pharetra tincidunt feugiat nisl imperdiet. Ut convallis libero in urna ultrices accumsan. Donec sed odio eros. Donec viverra mi quis quam pulvinar at malesuada arcu rhoncus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In rutrum accumsan ultricies. Mauris vitae nisi at sem facilisis semper ac in est.

-

Vivamus fermentum semper porta. Nunc diam velit, adipiscing ut tristique vitae, sagittis vel odio. Maecenas convallis ullamcorper ultricies. Curabitur ornare, ligula semper consectetur sagittis, nisi diam iaculis velit, id fringilla sem nunc vel mi. Nam dictum, odio nec pretium volutpat, arcu ante placerat erat, non tristique elit urna et turpis. Quisque mi metus, ornare sit amet fermentum et, tincidunt et orci. Fusce eget orci a orci congue vestibulum. Ut dolor diam, elementum et vestibulum eu, porttitor vel elit. Curabitur venenatis pulvinar tellus gravida ornare. Sed et erat faucibus nunc euismod ultricies ut id justo. Nullam cursus suscipit nisi, et ultrices justo sodales nec. Fusce venenatis facilisis lectus ac semper. Aliquam at massa ipsum. Quisque bibendum purus convallis nulla ultrices ultricies. Nullam aliquam, mi eu aliquam tincidunt, purus velit laoreet tortor, viverra pretium nisi quam vitae mi. Fusce vel volutpat elit. Nam sagittis nisi dui.

-

Vivamus fermentum semper porta. Nunc diam velit, adipiscing ut tristique vitae, sagittis vel odio. Maecenas convallis ullamcorper ultricies. Curabitur ornare, ligula semper consectetur sagittis, nisi diam iaculis velit, id fringilla sem nunc vel mi. Nam dictum, odio nec pretium volutpat, arcu ante placerat erat, non tristique elit urna et turpis. Quisque mi metus, ornare sit amet fermentum et, tincidunt et orci. Fusce eget orci a orci congue vestibulum. Ut dolor diam, elementum et vestibulum eu, porttitor vel elit. Curabitur venenatis pulvinar tellus gravida ornare. Sed et erat faucibus nunc euismod ultricies ut id justo. Nullam cursus suscipit nisi, et ultrices justo sodales nec. Fusce venenatis facilisis lectus ac semper. Aliquam at massa ipsum. Quisque bibendum purus convallis nulla ultrices ultricies. Nullam aliquam, mi eu aliquam tincidunt, purus velit laoreet tortor, viverra pretium nisi quam vitae mi. Fusce vel volutpat elit. Nam sagittis nisi dui.

-

Link to another page.

-

Vivamus fermentum semper porta. Nunc diam velit, adipiscing ut tristique vitae, sagittis vel odio. Maecenas convallis ullamcorper ultricies. Curabitur ornare, ligula semper consectetur sagittis, nisi diam iaculis velit, id fringilla sem nunc vel mi. Nam dictum, odio nec pretium volutpat, arcu ante placerat erat, non tristique elit urna et turpis. Quisque mi metus, ornare sit amet fermentum et, tincidunt et orci. Fusce eget orci a orci congue vestibulum. Ut dolor diam, elementum et vestibulum eu, porttitor vel elit. Curabitur venenatis pulvinar tellus gravida ornare. Sed et erat faucibus nunc euismod ultricies ut id justo. Nullam cursus suscipit nisi, et ultrices justo sodales nec. Fusce venenatis facilisis lectus ac semper. Aliquam at massa ipsum. Quisque bibendum purus convallis nulla ultrices ultricies. Nullam aliquam, mi eu aliquam tincidunt, purus velit laoreet tortor, viverra pretium nisi quam vitae mi. Fusce vel volutpat elit. Nam sagittis nisi dui.

-

Vivamus fermentum semper porta. Nunc diam velit, adipiscing ut tristique vitae, sagittis vel odio. Maecenas convallis ullamcorper ultricies. Curabitur ornare, ligula semper consectetur sagittis, nisi diam iaculis velit, id fringilla sem nunc vel mi. Nam dictum, odio nec pretium volutpat, arcu ante placerat erat, non tristique elit urna et turpis. Quisque mi metus, ornare sit amet fermentum et, tincidunt et orci. Fusce eget orci a orci congue vestibulum. Ut dolor diam, elementum et vestibulum eu, porttitor vel elit. Curabitur venenatis pulvinar tellus gravida ornare. Sed et erat faucibus nunc euismod ultricies ut id justo. Nullam cursus suscipit nisi, et ultrices justo sodales nec. Fusce venenatis facilisis lectus ac semper. Aliquam at massa ipsum. Quisque bibendum purus convallis nulla ultrices ultricies. Nullam aliquam, mi eu aliquam tincidunt, purus velit laoreet tortor, viverra pretium nisi quam vitae mi. Fusce vel volutpat elit. Nam sagittis nisi dui.

-
- - diff --git a/toolkit/components/reader/test/readerModeArticleHiddenNodes.html b/toolkit/components/reader/test/readerModeArticleHiddenNodes.html deleted file mode 100644 index 92441b7978..0000000000 --- a/toolkit/components/reader/test/readerModeArticleHiddenNodes.html +++ /dev/null @@ -1,22 +0,0 @@ - - - -Article title - - - - -
Site header
-
-

Article title

-

by Jane Doe

-

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ut gravida lorem. Ut turpis felis, pulvinar a semper sed, adipiscing id dolor. Pellentesque auctor nisi id magna consequat sagittis. Curabitur dapibus enim sit amet elit pharetra tincidunt feugiat nisl imperdiet. Ut convallis libero in urna ultrices accumsan. Donec sed odio eros. Donec viverra mi quis quam pulvinar at malesuada arcu rhoncus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In rutrum accumsan ultricies. Mauris vitae nisi at sem facilisis semper ac in est.

-

Vivamus fermentum semper porta. Nunc diam velit, adipiscing ut tristique vitae, sagittis vel odio. Maecenas convallis ullamcorper ultricies. Curabitur ornare, ligula semper consectetur sagittis, nisi diam iaculis velit, id fringilla sem nunc vel mi. Nam dictum, odio nec pretium volutpat, arcu ante placerat erat, non tristique elit urna et turpis. Quisque mi metus, ornare sit amet fermentum et, tincidunt et orci. Fusce eget orci a orci congue vestibulum. Ut dolor diam, elementum et vestibulum eu, porttitor vel elit. Curabitur venenatis pulvinar tellus gravida ornare. Sed et erat faucibus nunc euismod ultricies ut id justo. Nullam cursus suscipit nisi, et ultrices justo sodales nec. Fusce venenatis facilisis lectus ac semper. Aliquam at massa ipsum. Quisque bibendum purus convallis nulla ultrices ultricies. Nullam aliquam, mi eu aliquam tincidunt, purus velit laoreet tortor, viverra pretium nisi quam vitae mi. Fusce vel volutpat elit. Nam sagittis nisi dui.

-

Vivamus fermentum semper porta. Nunc diam velit, adipiscing ut tristique vitae, sagittis vel odio. Maecenas convallis ullamcorper ultricies. Curabitur ornare, ligula semper consectetur sagittis, nisi diam iaculis velit, id fringilla sem nunc vel mi. Nam dictum, odio nec pretium volutpat, arcu ante placerat erat, non tristique elit urna et turpis. Quisque mi metus, ornare sit amet fermentum et, tincidunt et orci. Fusce eget orci a orci congue vestibulum. Ut dolor diam, elementum et vestibulum eu, porttitor vel elit. Curabitur venenatis pulvinar tellus gravida ornare. Sed et erat faucibus nunc euismod ultricies ut id justo. Nullam cursus suscipit nisi, et ultrices justo sodales nec. Fusce venenatis facilisis lectus ac semper. Aliquam at massa ipsum. Quisque bibendum purus convallis nulla ultrices ultricies. Nullam aliquam, mi eu aliquam tincidunt, purus velit laoreet tortor, viverra pretium nisi quam vitae mi. Fusce vel volutpat elit. Nam sagittis nisi dui.

-

Vivamus fermentum semper porta. Nunc diam velit, adipiscing ut tristique vitae, sagittis vel odio. Maecenas convallis ullamcorper ultricies. Curabitur ornare, ligula semper consectetur sagittis, nisi diam iaculis velit, id fringilla sem nunc vel mi. Nam dictum, odio nec pretium volutpat, arcu ante placerat erat, non tristique elit urna et turpis. Quisque mi metus, ornare sit amet fermentum et, tincidunt et orci. Fusce eget orci a orci congue vestibulum. Ut dolor diam, elementum et vestibulum eu, porttitor vel elit. Curabitur venenatis pulvinar tellus gravida ornare. Sed et erat faucibus nunc euismod ultricies ut id justo. Nullam cursus suscipit nisi, et ultrices justo sodales nec. Fusce venenatis facilisis lectus ac semper. Aliquam at massa ipsum. Quisque bibendum purus convallis nulla ultrices ultricies. Nullam aliquam, mi eu aliquam tincidunt, purus velit laoreet tortor, viverra pretium nisi quam vitae mi. Fusce vel volutpat elit. Nam sagittis nisi dui.

-

Vivamus fermentum semper porta. Nunc diam velit, adipiscing ut tristique vitae, sagittis vel odio. Maecenas convallis ullamcorper ultricies. Curabitur ornare, ligula semper consectetur sagittis, nisi diam iaculis velit, id fringilla sem nunc vel mi. Nam dictum, odio nec pretium volutpat, arcu ante placerat erat, non tristique elit urna et turpis. Quisque mi metus, ornare sit amet fermentum et, tincidunt et orci. Fusce eget orci a orci congue vestibulum. Ut dolor diam, elementum et vestibulum eu, porttitor vel elit. Curabitur venenatis pulvinar tellus gravida ornare. Sed et erat faucibus nunc euismod ultricies ut id justo. Nullam cursus suscipit nisi, et ultrices justo sodales nec. Fusce venenatis facilisis lectus ac semper. Aliquam at massa ipsum. Quisque bibendum purus convallis nulla ultrices ultricies. Nullam aliquam, mi eu aliquam tincidunt, purus velit laoreet tortor, viverra pretium nisi quam vitae mi. Fusce vel volutpat elit. Nam sagittis nisi dui.

-
- - diff --git a/toolkit/components/reader/test/readerModeArticleMedium.html b/toolkit/components/reader/test/readerModeArticleMedium.html deleted file mode 100644 index 70b172cf63..0000000000 --- a/toolkit/components/reader/test/readerModeArticleMedium.html +++ /dev/null @@ -1,16 +0,0 @@ - - - -Article title - - - -
Site header
-
-

Article title

-

by Jane Doe

-

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ut gravida lorem. Ut turpis felis, pulvinar a semper sed, adipiscing id dolor. Pellentesque auctor nisi id magna consequat sagittis. Curabitur dapibus enim sit amet elit pharetra tincidunt feugiat nisl imperdiet. Ut convallis libero in urna ultrices accumsan. Donec sed odio eros. Donec viverra mi quis quam pulvinar at malesuada arcu rhoncus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetu

-

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ut gravida lorem. Ut turpis felis, pulvinar a semper sed, adipiscing id dolor. Pellentesque auctor nisi id magna consequat sagittis. Curabitur dapibus enim sit amet elit pharetra tincidunt feugiat nisl imperdiet. Ut convallis libero in urna ultrices accumsan. Donec sed odio eros. Donec viverra mi quis quam pulvinar at malesuada arcu rhoncus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetu

-

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ut gravida lorem. Ut turpis felis, pulvinar a semper sed, adipiscing id dolor. Pellentesque auctor nisi id magna consequat sagittis. Curabitur dapibus enim sit amet elit pharetra tincidunt feugiat nisl imperdiet. Ut convallis libero in urna ultrices accumsan. Donec sed odio eros. Donec viverra mi quis quam pulvinar at malesuada arcu rhoncus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetu

- - diff --git a/toolkit/components/reader/test/readerModeArticleShort.html b/toolkit/components/reader/test/readerModeArticleShort.html deleted file mode 100644 index 692471f27f..0000000000 --- a/toolkit/components/reader/test/readerModeArticleShort.html +++ /dev/null @@ -1,14 +0,0 @@ - - - -Article title - - - -
Site header
-
-

Article title

-

by Jane Doe

-

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ut gravida lorem. Ut turpis felis, pulvinar a semper sed, adipiscing id dolor. Pellentesque auctor nisi id magna consequat sagittis. Curabitur dapibus enim sit amet elit pharetra tincidunt feugiat nisl imperdiet. Ut convallis libero in urna ultrices accumsan. Donec sed odio eros. Donec viverra mi quis quam pulvinar at malesuada arcu rhoncus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetu

- - diff --git a/toolkit/components/reader/test/readerModeArticleTextPlain.txt b/toolkit/components/reader/test/readerModeArticleTextPlain.txt deleted file mode 100644 index c5b7861b73..0000000000 --- a/toolkit/components/reader/test/readerModeArticleTextPlain.txt +++ /dev/null @@ -1,10 +0,0 @@ - -Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Tortor id aliquet lectus proin nibh nisl condimentum. Eget magna fermentum iaculis eu non diam phasellus. Sed viverra tellus in hac habitasse platea dictumst. Quis commodo odio aenean sed. Diam vulputate ut pharetra sit amet aliquam id diam. Felis imperdiet proin fermentum leo vel orci. Diam vel quam elementum pulvinar. Vestibulum lectus mauris ultrices eros in cursus turpis massa. Sagittis vitae et leo duis ut diam. Quam elementum pulvinar etiam non quam lacus suspendisse faucibus interdum. At augue eget arcu dictum varius duis at consectetur. Bibendum enim facilisis gravida neque convallis a cras semper auctor. Suspendisse interdum consectetur libero id faucibus. Neque ornare aenean euismod elementum nisi. - -Lacus sed turpis tincidunt id aliquet. Euismod nisi porta lorem mollis. Sollicitudin aliquam ultrices sagittis orci. A diam sollicitudin tempor id eu nisl nunc. Molestie a iaculis at erat pellentesque adipiscing commodo elit. Tellus mauris a diam maecenas. Dolor morbi non arcu risus quis. Dictum non consectetur a erat nam at lectus. Convallis posuere morbi leo urna molestie. Blandit turpis cursus in hac habitasse platea dictumst quisque sagittis. Sed ullamcorper morbi tincidunt ornare massa eget egestas. Sit amet risus nullam eget felis eget nunc. Turpis in eu mi bibendum neque egestas congue. Accumsan in nisl nisi scelerisque eu ultrices vitae. Vel quam elementum pulvinar etiam non quam lacus. - -Erat velit scelerisque in dictum non consectetur a. Vulputate sapien nec sagittis aliquam malesuada bibendum. Odio facilisis mauris sit amet massa vitae tortor condimentum lacinia. Tempor nec feugiat nisl pretium. At urna condimentum mattis pellentesque id nibh tortor. Viverra tellus in hac habitasse platea dictumst. Turpis massa tincidunt dui ut ornare. Nunc id cursus metus aliquam eleifend mi. Etiam dignissim diam quis enim lobortis scelerisque fermentum. Aenean sed adipiscing diam donec adipiscing tristique risus nec feugiat. Vitae aliquet nec ullamcorper sit amet risus nullam eget felis. Quis hendrerit dolor magna eget est lorem ipsum dolor. Ultrices vitae auctor eu augue ut lectus. Curabitur gravida arcu ac tortor dignissim convallis. Justo laoreet sit amet cursus sit. Lorem ipsum dolor sit amet. Sed sed risus pretium quam vulputate dignissim suspendisse in. - -Egestas erat imperdiet sed euismod nisi porta lorem mollis. Pharetra magna ac placerat vestibulum lectus mauris ultrices eros in. Est ante in nibh mauris cursus mattis. Habitasse platea dictumst vestibulum rhoncus est pellentesque elit ullamcorper dignissim. Nunc aliquet bibendum enim facilisis gravida neque. Massa sapien faucibus et molestie. Sapien eget mi proin sed libero enim sed faucibus. Mauris a diam maecenas sed enim ut sem. Consectetur adipiscing elit duis tristique sollicitudin nibh sit. Sed arcu non odio euismod lacinia at. - -Ultricies mi quis hendrerit dolor. A erat nam at lectus urna duis convallis convallis tellus. Est sit amet facilisis magna etiam tempor orci. Porttitor massa id neque aliquam vestibulum. Lobortis feugiat vivamus at augue eget arcu dictum varius duis. Diam sit amet nisl suscipit adipiscing. Leo in vitae turpis massa. Netus et malesuada fames ac. Ac turpis egestas sed tempus urna et pharetra. Ut eu sem integer vitae justo. At erat pellentesque adipiscing commodo elit at. Consectetur purus ut faucibus pulvinar elementum integer enim. Cursus eget nunc scelerisque viverra mauris in aliquam sem. Aenean et tortor at risus viverra adipiscing at in. Platea dictumst vestibulum rhoncus est pellentesque elit ullamcorper dignissim cras. Tincidunt id aliquet risus feugiat in ante. Amet consectetur adipiscing elit pellentesque. Dignissim enim sit amet venenatis urna cursus eget nunc. Sit amet porttitor eget dolor morbi non. diff --git a/toolkit/components/reader/test/readerModeNonArticle.html b/toolkit/components/reader/test/readerModeNonArticle.html deleted file mode 100644 index e216af3c1f..0000000000 --- a/toolkit/components/reader/test/readerModeNonArticle.html +++ /dev/null @@ -1,9 +0,0 @@ - - - -Non article title - - - - - diff --git a/toolkit/components/reader/test/readerModeRandom.sjs b/toolkit/components/reader/test/readerModeRandom.sjs deleted file mode 100644 index f6bb15c06a..0000000000 --- a/toolkit/components/reader/test/readerModeRandom.sjs +++ /dev/null @@ -1,23 +0,0 @@ -// Generate a article ending in a piece of text with some random values in it. - -let readerModeText = ` - - -Article title - - - -
Site header
-
-

Article title

-

by Jane Doe

-

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ut gravida lorem. Ut turpis felis, pulvinar a semper sed, adipiscing id dolor. Pellentesque auctor nisi id magna consequat sagittis. Curabitur dapibus enim sit amet elit pharetra tincidunt feugiat nisl imperdiet. Ut convallis libero in urna ultrices accumsan. Donec sed odio eros. Donec viverra mi quis quam pulvinar at malesuada arcu rhoncus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetu

-`; - -function handleRequest(aRequest, aResponse) { - aResponse.setStatusLine(aRequest.httpVersion, 200); - aResponse.setHeader("Content-Type", "text/html", false); - aResponse.write( - readerModeText + "

" + Date.now() + "," + Math.random() + "

" - ); -} diff --git a/toolkit/components/reader/test/setSameSiteCookie.html b/toolkit/components/reader/test/setSameSiteCookie.html deleted file mode 100644 index 67bb714922..0000000000 --- a/toolkit/components/reader/test/setSameSiteCookie.html +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - -

This page just set a cookie with the SameSite attribute.

- - diff --git a/toolkit/components/reader/test/setSameSiteCookie.html^headers^ b/toolkit/components/reader/test/setSameSiteCookie.html^headers^ deleted file mode 100644 index c0229c93b6..0000000000 --- a/toolkit/components/reader/test/setSameSiteCookie.html^headers^ +++ /dev/null @@ -1 +0,0 @@ -Set-Cookie: foo=bar; Path='/' ; SameSite=strict diff --git a/toolkit/components/reader/tests/browser/browser.toml b/toolkit/components/reader/tests/browser/browser.toml new file mode 100644 index 0000000000..9382e6d60f --- /dev/null +++ b/toolkit/components/reader/tests/browser/browser.toml @@ -0,0 +1,76 @@ +[DEFAULT] +support-files = ["head.js"] + +["browser_bug1124271_readerModePinnedTab.js"] +support-files = ["readerModeArticle.html"] + +["browser_bug1453818_samesite_cookie.js"] +support-files = [ + "getCookies.sjs", + "linkToGetCookies.html", + "setSameSiteCookie.html", + "setSameSiteCookie.html^headers^", +] + +["browser_bug1780350_readerModeSaveScroll.js"] +support-files = ["readerModeArticleContainsLink.html"] + +["browser_drag_url_readerMode.js"] +support-files = ["readerModeArticle.html"] + +["browser_localfile_readerMode.js"] +support-files = ["readerModeArticle.html"] + +["browser_readerMode.js"] +support-files = [ + "readerModeNonArticle.html", + "readerModeArticle.html", + "readerModeArticleHiddenNodes.html", +] + +["browser_readerMode_bc_reuse.js"] +support-files = ["readerModeArticle.html"] + +["browser_readerMode_cached.js"] +support-files = ["readerModeRandom.sjs"] + +["browser_readerMode_colorSchemePref.js"] +support-files = ["readerModeArticle.html"] + +["browser_readerMode_hidden_nodes.js"] +support-files = ["readerModeArticleHiddenNodes.html"] + +["browser_readerMode_menu.js"] +support-files = ["readerModeArticleShort.html"] + +["browser_readerMode_pocket.js"] +support-files = [ + "readerModeArticleShort.html", + "readerModeArticleMedium.html", +] + +["browser_readerMode_readingTime.js"] +support-files = [ + "readerModeArticle.html", + "readerModeArticleShort.html", + "readerModeArticleMedium.html", +] + +["browser_readerMode_refresh.js"] +support-files = [ + "readerModeArticleShort.html", + "readerModeArticleTextPlain.txt", +] + +["browser_readerMode_remoteType.js"] +support-files = ["readerModeArticleShort.html"] + +["browser_readerMode_samesite_cookie_redirect.js"] +support-files = [ + "getCookies.sjs", + "setSameSiteCookie.html", + "setSameSiteCookie.html^headers^", +] + +["browser_readerMode_with_anchor.js"] +support-files = ["readerModeArticle.html"] diff --git a/toolkit/components/reader/tests/browser/browser_bug1124271_readerModePinnedTab.js b/toolkit/components/reader/tests/browser/browser_bug1124271_readerModePinnedTab.js new file mode 100644 index 0000000000..346d503675 --- /dev/null +++ b/toolkit/components/reader/tests/browser/browser_bug1124271_readerModePinnedTab.js @@ -0,0 +1,53 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +// Test that the reader mode button won't open in a new tab when clicked from a pinned tab + +const PREF = "reader.parse-on-load.enabled"; + +const TEST_PATH = getRootDirectory(gTestPath).replace( + "chrome://mochitests/content", + "https://example.com" +); + +var readerButton = document.getElementById("reader-mode-button"); + +add_task(async function () { + registerCleanupFunction(function () { + Services.prefs.clearUserPref(PREF); + while (gBrowser.tabs.length > 1) { + gBrowser.removeCurrentTab(); + } + }); + + // Enable the reader mode button. + Services.prefs.setBoolPref(PREF, true); + + let tab = (gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser)); + gBrowser.pinTab(tab); + + let initialTabsCount = gBrowser.tabs.length; + + // Point tab to a test page that is reader-able. + let url = TEST_PATH + "readerModeArticle.html"; + await promiseTabLoadEvent(tab, url); + await TestUtils.waitForCondition(() => !readerButton.hidden); + + readerButton.click(); + await promiseTabLoadEvent(tab); + + // Ensure no new tabs are opened when exiting reader mode in a pinned tab + is(gBrowser.tabs.length, initialTabsCount, "No additional tabs were opened."); + + let pageShownPromise = BrowserTestUtils.waitForContentEvent( + tab.linkedBrowser, + "pageshow" + ); + readerButton.click(); + await pageShownPromise; + // Ensure no new tabs are opened when exiting reader mode in a pinned tab + is(gBrowser.tabs.length, initialTabsCount, "No additional tabs were opened."); + + gBrowser.removeCurrentTab(); +}); diff --git a/toolkit/components/reader/tests/browser/browser_bug1453818_samesite_cookie.js b/toolkit/components/reader/tests/browser/browser_bug1453818_samesite_cookie.js new file mode 100644 index 0000000000..1fbfdeabfb --- /dev/null +++ b/toolkit/components/reader/tests/browser/browser_bug1453818_samesite_cookie.js @@ -0,0 +1,132 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const TEST_ORIGIN1 = getRootDirectory(gTestPath).replace( + "chrome://mochitests/content", + "http://example.com" +); +const TEST_ORIGIN2 = getRootDirectory(gTestPath).replace( + "chrome://mochitests/content", + "http://example.org" +); + +async function clickLink(browser) { + info("Waiting for the page to load after clicking the link..."); + let pageLoaded = BrowserTestUtils.waitForContentEvent( + browser, + "DOMContentLoaded" + ); + await SpecialPowers.spawn(browser, [], async function () { + let link = content.document.getElementById("link"); + ok(link, "The link element was found."); + link.click(); + }); + await pageLoaded; +} + +async function checkCookiePresent(browser) { + await SpecialPowers.spawn(browser, [], async function () { + let cookieSpan = content.document.getElementById("cookieSpan"); + ok(cookieSpan, "cookieSpan element should be in document"); + is( + cookieSpan.textContent, + "foo=bar", + "The SameSite cookie was sent correctly." + ); + }); +} + +async function checkCookie(browser) { + info("Check that the SameSite cookie was not sent."); + await SpecialPowers.spawn(browser, [], async function () { + let cookieSpan = content.document.getElementById("cookieSpan"); + ok(cookieSpan, "cookieSpan element should be in document"); + is( + cookieSpan.textContent, + "", + "The SameSite cookie was blocked correctly." + ); + }); +} + +async function runTest() { + await SpecialPowers.pushPrefEnv({ + set: [["reader.parse-on-load.enabled", true]], + }); + + info("Set a SameSite=strict cookie."); + await BrowserTestUtils.withNewTab( + TEST_ORIGIN1 + "setSameSiteCookie.html", + () => {} + ); + + info("Check that the cookie has been correctly set."); + await BrowserTestUtils.withNewTab( + TEST_ORIGIN1 + "getCookies.sjs", + async function (browser) { + await checkCookiePresent(browser); + } + ); + + info( + "Open a cross-origin page with a link to the domain that set the cookie." + ); + { + let browser; + let pageLoaded; + let tab = await BrowserTestUtils.openNewForegroundTab( + gBrowser, + () => { + let t = BrowserTestUtils.addTab( + gBrowser, + TEST_ORIGIN2 + "linkToGetCookies.html" + ); + gBrowser.selectedTab = t; + browser = gBrowser.selectedBrowser; + pageLoaded = BrowserTestUtils.waitForContentEvent( + browser, + "DOMContentLoaded" + ); + return t; + }, + false + ); + + info("Waiting for the page to load in normal mode..."); + await pageLoaded; + + await clickLink(browser); + await checkCookie(browser); + await BrowserTestUtils.removeTab(tab); + } + + info("Open the cross-origin page again."); + await BrowserTestUtils.withNewTab( + TEST_ORIGIN2 + "linkToGetCookies.html", + async function (browser) { + let pageShown = BrowserTestUtils.waitForContentEvent( + browser, + "AboutReaderContentReady" + ); + let readerButton = document.getElementById("reader-mode-button"); + ok(readerButton, "readerButton should be available"); + readerButton.click(); + + info("Waiting for the page to be displayed in reader mode..."); + await pageShown; + + await clickLink(browser); + await checkCookie(browser); + } + ); +} + +add_task(async function () { + await runTest(true); +}); + +add_task(async function () { + await runTest(false); +}); diff --git a/toolkit/components/reader/tests/browser/browser_bug1780350_readerModeSaveScroll.js b/toolkit/components/reader/tests/browser/browser_bug1780350_readerModeSaveScroll.js new file mode 100644 index 0000000000..76add5511e --- /dev/null +++ b/toolkit/components/reader/tests/browser/browser_bug1780350_readerModeSaveScroll.js @@ -0,0 +1,70 @@ +/* eslint-disable @microsoft/sdl/no-insecure-url */ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ +"use strict"; + +const TEST_PATH = getRootDirectory(gTestPath).replace( + "chrome://mochitests/content", + "http://example.com" +); + +// This test verifies that when a link is clicked from +// within reader view, when navigating back to reader view +// the previous scroll position of the page is restored. +add_task(async function test_save_scroll_position() { + await BrowserTestUtils.withNewTab( + TEST_PATH + "readerModeArticleContainsLink.html", + async function (browser) { + let pageShownPromise = BrowserTestUtils.waitForContentEvent( + browser, + "AboutReaderContentReady" + ); + let browserLoadedPromise = BrowserTestUtils.browserLoaded(browser); + let readerButton = document.getElementById("reader-mode-button"); + readerButton.click(); + await Promise.all([pageShownPromise, browserLoadedPromise]); + let scrollEventPromise = BrowserTestUtils.waitForContentEvent( + browser, + "scroll", + true + ); + // Set scroll position in reader to 200px down. + await SpecialPowers.spawn(browser, [], async function () { + content.document.documentElement.scrollTop = 200; + }); + await scrollEventPromise; + + // Click linked page and check that scroll pos resets. + await SpecialPowers.spawn(browser, [], async function () { + let linkElement = content.document.getElementById("link"); + linkElement.click(); + }); + await BrowserTestUtils.browserLoaded(browser); + await SpecialPowers.spawn(browser, [], async function () { + is( + content.document.documentElement.scrollTop, + 0, + "vertical scroll position should reset to zero when navigating to linked page." + ); + content.window.history.back(); + }); + + // Navigate back to reader and check that scroll position is restored. + await BrowserTestUtils.browserLoaded(browser); + scrollEventPromise = BrowserTestUtils.waitForContentEvent( + browser, + "scroll", + true + ); + await scrollEventPromise; + await SpecialPowers.spawn(browser, [], async function () { + let doc = content.document; + is( + doc.documentElement.scrollTop, + 200, + "should restore saved scroll position when navigating back from link." + ); + }); + } + ); +}); diff --git a/toolkit/components/reader/tests/browser/browser_drag_url_readerMode.js b/toolkit/components/reader/tests/browser/browser_drag_url_readerMode.js new file mode 100644 index 0000000000..2dae1872c3 --- /dev/null +++ b/toolkit/components/reader/tests/browser/browser_drag_url_readerMode.js @@ -0,0 +1,61 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const TEST_PATH = getRootDirectory(gTestPath).replace( + "chrome://mochitests/content", + "http://example.com" +); + +add_task(async function test_readerModeURLDrag() { + await BrowserTestUtils.withNewTab( + { + gBrowser, + url: TEST_PATH + "readerModeArticle.html", + }, + + async browser => { + let readerButton = document.getElementById("reader-mode-button"); + await TestUtils.waitForCondition( + () => !readerButton.hidden, + "Reader mode button should become visible" + ); + + is_element_visible( + readerButton, + "Reader mode button is present on a reader-able page" + ); + + // Switch page into reader mode. + let promiseTabLoad = BrowserTestUtils.browserLoaded(browser); + readerButton.click(); + await promiseTabLoad; + let urlbar = document.getElementById("urlbar-input"); + let readerUrl = gBrowser.selectedBrowser.currentURI.spec; + ok( + readerUrl.startsWith("about:reader"), + "about:reader loaded after clicking reader mode button" + ); + + let dataTran = new DataTransfer(); + let urlEvent = new DragEvent("dragstart", { dataTransfer: dataTran }); + let oldUrl = TEST_PATH + "readerModeArticle.html"; + let urlBarContainer = document.getElementById("urlbar-input-container"); + // We intentionally turn off a11y_checks for the following click, because + // it is send to prepare the URL Bar for the mouse-specific action - for a + // drag event, while there are other ways are accessible for users of + // assistive technology and keyboards, therefore this test can be excluded + // from the accessibility tests. + AccessibilityUtils.setEnv({ mustHaveAccessibleRule: false }); + urlBarContainer.click(); + AccessibilityUtils.resetEnv(); + urlbar.dispatchEvent(urlEvent); + + let newUrl = urlEvent.dataTransfer.getData("text/plain"); + ok(!newUrl.includes("about:reader"), "URL does not contain about:reader"); + + Assert.equal(newUrl, oldUrl, "URL is the same"); + } + ); +}); diff --git a/toolkit/components/reader/tests/browser/browser_localfile_readerMode.js b/toolkit/components/reader/tests/browser/browser_localfile_readerMode.js new file mode 100644 index 0000000000..118e4bb23f --- /dev/null +++ b/toolkit/components/reader/tests/browser/browser_localfile_readerMode.js @@ -0,0 +1,54 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const TEST_BASE_URI = getResolvedURI(getRootDirectory(gTestPath)).spec; + +let readerButton = document.getElementById("reader-mode-button"); + +/** + * Reader mode should work on local files. + */ +add_task(async function test_readermode_available_for_local_files() { + await BrowserTestUtils.withNewTab( + TEST_BASE_URI + "readerModeArticle.html", + async function (browser) { + await TestUtils.waitForCondition( + () => !readerButton.hidden, + "Reader mode button should become visible" + ); + + is_element_visible( + readerButton, + "Reader mode button is present on a reader-able page" + ); + + // Switch page into reader mode. + let promiseTabLoad = BrowserTestUtils.browserLoaded(browser); + readerButton.click(); + await promiseTabLoad; + + let readerUrl = gBrowser.selectedBrowser.currentURI.spec; + ok( + readerUrl.startsWith("about:reader"), + "about:reader loaded after clicking reader mode button" + ); + is_element_visible( + readerButton, + "Reader mode button is present on about:reader" + ); + + is( + gURLBar.untrimmedValue, + TEST_BASE_URI + "readerModeArticle.html", + "gURLBar value is about:reader URL" + ); + is( + gURLBar.value, + gURLBar.untrimmedValue, + "gURLBar is displaying original article URL" + ); + } + ); +}); diff --git a/toolkit/components/reader/tests/browser/browser_readerMode.js b/toolkit/components/reader/tests/browser/browser_readerMode.js new file mode 100644 index 0000000000..9093aa7fc1 --- /dev/null +++ b/toolkit/components/reader/tests/browser/browser_readerMode.js @@ -0,0 +1,399 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/** + * Test that the reader mode button appears and works properly on + * reader-able content. + */ +const TEST_PREFS = [["reader.parse-on-load.enabled", true]]; + +const TEST_PATH = getRootDirectory(gTestPath).replace( + "chrome://mochitests/content", + "https://example.com" +); + +var readerButton = document.getElementById("reader-mode-button"); + +ChromeUtils.defineESModuleGetters(this, { + PlacesTestUtils: "resource://testing-common/PlacesTestUtils.sys.mjs", + UrlbarTestUtils: "resource://testing-common/UrlbarTestUtils.sys.mjs", +}); + +add_task(async function test_reader_button() { + registerCleanupFunction(function () { + // Reset test prefs. + TEST_PREFS.forEach(([name]) => { + Services.prefs.clearUserPref(name); + }); + while (gBrowser.tabs.length > 1) { + gBrowser.removeCurrentTab(); + } + }); + + // Set required test prefs. + TEST_PREFS.forEach(([name, value]) => { + Services.prefs.setBoolPref(name, value); + }); + + let tab = (gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser)); + is_element_hidden( + readerButton, + "Reader mode button is not present on a new tab" + ); + ok( + !UITour.isInfoOnTarget(window, "readerMode-urlBar"), + "Info panel shouldn't appear without the reader mode button" + ); + + // Point tab to a test page that is reader-able. + let url = TEST_PATH + "readerModeArticle.html"; + // Set up favicon for testing. + let favicon = + "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAA" + + "AAAA6fptVAAAACklEQVQI12NgAAAAAgAB4iG8MwAAAABJRU5ErkJggg=="; + info("Adding visit so we can add favicon"); + await PlacesTestUtils.addVisits(new URL(url)); + info("Adding favicon"); + await PlacesTestUtils.addFavicons(new Map([[url, favicon]])); + info("Opening tab and waiting for reader mode button to show up"); + + await promiseTabLoadEvent(tab, url); + await TestUtils.waitForCondition(() => !readerButton.hidden); + + is_element_visible( + readerButton, + "Reader mode button is present on a reader-able page" + ); + + // Switch page into reader mode. + let promiseTabLoad = promiseTabLoadEvent(tab); + readerButton.click(); + await promiseTabLoad; + + let readerUrl = gBrowser.selectedBrowser.currentURI.spec; + ok( + readerUrl.startsWith("about:reader"), + "about:reader loaded after clicking reader mode button" + ); + is_element_visible( + readerButton, + "Reader mode button is present on about:reader" + ); + let iconEl = tab.iconImage; + await TestUtils.waitForCondition( + () => iconEl.getBoundingClientRect().width != 0 + ); + is_element_visible(iconEl, "Favicon should be visible"); + is(iconEl.src, favicon, "Correct favicon should be loaded"); + + is(gURLBar.untrimmedValue, url, "gURLBar value is about:reader URL"); + is( + gURLBar.value, + UrlbarTestUtils.trimURL(url), + "gURLBar is displaying original article URL" + ); + + // Check selected value for URL bar + await new Promise((resolve, reject) => { + waitForClipboard( + url, + function () { + gURLBar.focus(); + gURLBar.select(); + goDoCommand("cmd_copy"); + }, + resolve, + reject + ); + }); + + info("Got correct URL when copying"); + + // Switch page back out of reader mode. + let promisePageShow = BrowserTestUtils.waitForContentEvent( + tab.linkedBrowser, + "pageshow", + false, + e => e.target.location.href != "about:blank" + ); + readerButton.click(); + await promisePageShow; + is( + gBrowser.selectedBrowser.currentURI.spec, + url, + "Back to the original page after clicking active reader mode button" + ); + ok( + gBrowser.selectedBrowser.canGoForward, + "Moved one step back in the session history." + ); + + let nonReadableUrl = TEST_PATH + "readerModeNonArticle.html"; + + // Load a new tab that is NOT reader-able. + let newTab = (gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser)); + await promiseTabLoadEvent(newTab, nonReadableUrl); + await TestUtils.waitForCondition(() => readerButton.hidden); + is_element_hidden( + readerButton, + "Reader mode button is not present on a non-reader-able page" + ); + + // Switch back to the original tab to make sure reader mode button is still visible. + gBrowser.removeCurrentTab(); + await TestUtils.waitForCondition(() => !readerButton.hidden); + is_element_visible( + readerButton, + "Reader mode button is present on a reader-able page" + ); + + // Load a new tab in reader mode that is NOT reader-able in the reader mode. + newTab = gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser); + let promiseAboutReaderError = BrowserTestUtils.waitForContentEvent( + newTab.linkedBrowser, + "AboutReaderContentError" + ); + await promiseTabLoadEvent(newTab, "about:reader?url=" + nonReadableUrl); + await promiseAboutReaderError; + await TestUtils.waitForCondition(() => !readerButton.hidden); + is_element_visible( + readerButton, + "Reader mode button is present on about:reader even in error state" + ); + + // Switch page back out of reader mode. + promisePageShow = BrowserTestUtils.waitForContentEvent( + newTab.linkedBrowser, + "pageshow", + false, + e => e.target.location.href != "about:blank" + ); + readerButton.click(); + await promisePageShow; + is( + gBrowser.selectedBrowser.currentURI.spec, + nonReadableUrl, + "Back to the original non-reader-able page after clicking active reader mode button" + ); + await TestUtils.waitForCondition(() => readerButton.hidden); + is_element_hidden( + readerButton, + "Reader mode button is not present on a non-reader-able page" + ); +}); + +add_task(async function test_getOriginalUrl() { + let { ReaderMode } = ChromeUtils.importESModule( + "resource://gre/modules/ReaderMode.sys.mjs" + ); + let url = "https://foo.com/article.html"; + + is( + ReaderMode.getOriginalUrl("about:reader?url=" + encodeURIComponent(url)), + url, + "Found original URL from encoded URL" + ); + is( + ReaderMode.getOriginalUrl("about:reader?foobar"), + null, + "Did not find original URL from malformed reader URL" + ); + is( + ReaderMode.getOriginalUrl(url), + null, + "Did not find original URL from non-reader URL" + ); + + let badUrl = "https://foo.com/?;$%^^"; + is( + ReaderMode.getOriginalUrl("about:reader?url=" + encodeURIComponent(badUrl)), + badUrl, + "Found original URL from encoded malformed URL" + ); + is( + ReaderMode.getOriginalUrl("about:reader?url=" + badUrl), + badUrl, + "Found original URL from non-encoded malformed URL" + ); +}); + +add_task(async function test_reader_view_element_attribute_transform() { + registerCleanupFunction(function () { + while (gBrowser.tabs.length > 1) { + gBrowser.removeCurrentTab(); + } + }); + + function observeAttribute(element, attributes, triggerFn, checkFn) { + return new Promise(resolve => { + let observer = new MutationObserver(mutations => { + for (let mu of mutations) { + if (element.getAttribute(mu.attributeName) !== mu.oldValue) { + if (checkFn()) { + resolve(); + observer.disconnect(); + return; + } + } + } + }); + + observer.observe(element, { + attributes: true, + attributeOldValue: true, + attributeFilter: Array.isArray(attributes) ? attributes : [attributes], + }); + + triggerFn(); + }); + } + + let menuitem = document.getElementById("menu_readerModeItem"); + let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser); + is( + menuitem.hidden, + true, + "menuitem element should have the hidden attribute" + ); + + info("Navigate a reader-able page"); + function waitForNonBlankPage() { + return BrowserTestUtils.waitForContentEvent( + tab.linkedBrowser, + "pageshow", + false, + e => e.target.location.href != "about:blank" + ); + } + let waitForPageshow = waitForNonBlankPage(); + await observeAttribute( + menuitem, + "hidden", + () => { + let url = TEST_PATH + "readerModeArticle.html"; + BrowserTestUtils.startLoadingURIString(tab.linkedBrowser, url); + }, + () => !menuitem.hidden + ); + is( + menuitem.hidden, + false, + "menuitem's hidden attribute should be false on a reader-able page" + ); + await waitForPageshow; + + info("Navigate a non-reader-able page"); + waitForPageshow = waitForNonBlankPage(); + await observeAttribute( + menuitem, + "hidden", + () => { + let url = TEST_PATH + "readerModeArticleHiddenNodes.html"; + BrowserTestUtils.startLoadingURIString(tab.linkedBrowser, url); + }, + () => menuitem.hidden + ); + is( + menuitem.hidden, + true, + "menuitem's hidden attribute should be true on a non-reader-able page" + ); + await waitForPageshow; + + info("Navigate a reader-able page"); + waitForPageshow = waitForNonBlankPage(); + await observeAttribute( + menuitem, + "hidden", + () => { + let url = TEST_PATH + "readerModeArticle.html"; + BrowserTestUtils.startLoadingURIString(tab.linkedBrowser, url); + }, + () => !menuitem.hidden + ); + is( + menuitem.hidden, + false, + "menuitem's hidden attribute should be false on a reader-able page" + ); + await waitForPageshow; + + info("Enter Reader Mode"); + waitForPageshow = waitForNonBlankPage(); + await observeAttribute( + readerButton, + "readeractive", + () => { + readerButton.click(); + }, + () => readerButton.getAttribute("readeractive") == "true" + ); + is( + readerButton.getAttribute("readeractive"), + "true", + "readerButton's readeractive attribute should be true when entering reader mode" + ); + await waitForPageshow; + + info("Exit Reader Mode"); + waitForPageshow = waitForNonBlankPage(); + await observeAttribute( + readerButton, + ["readeractive", "hidden"], + () => { + readerButton.click(); + }, + () => { + info( + `active: ${readerButton.getAttribute("readeractive")}; hidden: ${ + menuitem.hidden + }` + ); + return !readerButton.getAttribute("readeractive") && !menuitem.hidden; + } + ); + ok( + !readerButton.getAttribute("readeractive"), + "readerButton's readeractive attribute should be empty when reader mode is exited" + ); + ok(!menuitem.hidden, "menuitem should not be hidden."); + await waitForPageshow; + + info("Navigate a non-reader-able page"); + waitForPageshow = waitForNonBlankPage(); + await observeAttribute( + menuitem, + "hidden", + () => { + let url = TEST_PATH + "readerModeArticleHiddenNodes.html"; + BrowserTestUtils.startLoadingURIString(tab.linkedBrowser, url); + }, + () => menuitem.hidden + ); + is( + menuitem.hidden, + true, + "menuitem's hidden attribute should be true on a non-reader-able page" + ); + await waitForPageshow; +}); + +add_task(async function test_reader_mode_lang() { + let url = TEST_PATH + "readerModeArticle.html"; + let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser); + BrowserTestUtils.startLoadingURIString(tab.linkedBrowser, url); + + await promiseTabLoadEvent(tab, url); + await TestUtils.waitForCondition(() => !readerButton.hidden); + + // Switch page into reader mode. + let promiseTabLoad = promiseTabLoadEvent(tab); + readerButton.click(); + await promiseTabLoad; + + await SpecialPowers.spawn(gBrowser.selectedBrowser, [], () => { + let container = content.document.querySelector(".container"); + is(container.lang, "en"); + }); +}); diff --git a/toolkit/components/reader/tests/browser/browser_readerMode_bc_reuse.js b/toolkit/components/reader/tests/browser/browser_readerMode_bc_reuse.js new file mode 100644 index 0000000000..9ac0e367ca --- /dev/null +++ b/toolkit/components/reader/tests/browser/browser_readerMode_bc_reuse.js @@ -0,0 +1,44 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const TEST_PATH = getRootDirectory(gTestPath).replace( + "chrome://mochitests/content", + "http://example.com" +); + +const TEST_URL = TEST_PATH + "readerModeArticle.html"; + +add_task(async function test_TODO() { + await BrowserTestUtils.withNewTab( + "data:text/html,

Opener", + async browser => { + let newTabPromise = BrowserTestUtils.waitForNewTab( + gBrowser, + TEST_URL, + true + ); + await SpecialPowers.spawn(browser, [TEST_URL], url => { + content.eval(`window.x = open("${url}", "_blank");`); + }); + let newTab = await newTabPromise; + + let readerButton = document.getElementById("reader-mode-button"); + await BrowserTestUtils.waitForMutationCondition( + readerButton, + { attributes: true }, + () => !readerButton.hidden + ); + let tabLoaded = promiseTabLoadEvent(newTab); + readerButton.click(); + await tabLoaded; + isnot( + newTab.linkedBrowser.browsingContext.group.id, + browser.browsingContext.group.id, + "BC should be in a different group now." + ); + BrowserTestUtils.removeTab(newTab); + } + ); +}); diff --git a/toolkit/components/reader/tests/browser/browser_readerMode_cached.js b/toolkit/components/reader/tests/browser/browser_readerMode_cached.js new file mode 100644 index 0000000000..ca9dd4a447 --- /dev/null +++ b/toolkit/components/reader/tests/browser/browser_readerMode_cached.js @@ -0,0 +1,32 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ +"use strict"; + +// This test verifies that the article is properly using the cached data +// when switching into reader mode. The article produces a random number +// contained within it, so if the article gets reloaded instead of using +// the cached version, it would have a different value in it. +const URL = + "http://mochi.test:8888/browser/toolkit/components/reader/tests/browser/readerModeRandom.sjs"; + +add_task(async function () { + let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, URL); + + let randomNumber = await SpecialPowers.spawn(tab.linkedBrowser, [], () => { + return content.document.getElementById("rnd").textContent; + }); + + let promiseTabLoad = promiseTabLoadEvent(tab); + let readerButton = document.getElementById("reader-mode-button"); + readerButton.click(); + await promiseTabLoad; + await TestUtils.waitForCondition(() => !readerButton.hidden); + + let newRandomNumber = await SpecialPowers.spawn(tab.linkedBrowser, [], () => { + return content.document.getElementById("rnd").textContent; + }); + + is(randomNumber, newRandomNumber, "used the same value"); + + BrowserTestUtils.removeTab(tab); +}); diff --git a/toolkit/components/reader/tests/browser/browser_readerMode_colorSchemePref.js b/toolkit/components/reader/tests/browser/browser_readerMode_colorSchemePref.js new file mode 100644 index 0000000000..73d3f160b8 --- /dev/null +++ b/toolkit/components/reader/tests/browser/browser_readerMode_colorSchemePref.js @@ -0,0 +1,121 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +const TEST_PATH = getRootDirectory(gTestPath).replace( + "chrome://mochitests/content", + "http://example.com" +); + +async function testColorScheme(aPref, aExpectation) { + // Set the browser content theme to light or dark. + Services.prefs.setIntPref("browser.theme.content-theme", aPref); + + // Reader Mode Color Scheme Preference must be manually set by the user, will + // default to "auto" initially. + Services.prefs.setCharPref("reader.color_scheme", aExpectation); + + let aBodyExpectation = aExpectation; + if (aBodyExpectation === "auto") { + aBodyExpectation = aPref === 1 ? "light" : "dark"; + } + + // Open a browser tab, enter reader mode, and test if we have the valid + // reader mode color scheme preference pre-selected. + await BrowserTestUtils.withNewTab( + TEST_PATH + "readerModeArticle.html", + async function (browser) { + let pageShownPromise = BrowserTestUtils.waitForContentEvent( + browser, + "AboutReaderContentReady" + ); + + let readerButton = document.getElementById("reader-mode-button"); + readerButton.click(); + await pageShownPromise; + + let colorScheme = Services.prefs.getCharPref("reader.color_scheme"); + + Assert.equal(colorScheme, aExpectation); + + await SpecialPowers.spawn(browser, [aBodyExpectation], expectation => { + let bodyClass = content.document.body.className; + ok( + bodyClass.includes(expectation), + "The body of the test document has the correct color scheme." + ); + }); + } + ); +} + +/** + * Test that opening reader mode maintains the correct color scheme preference + * until the user manually sets a different color scheme. + */ +add_task(async function () { + await testColorScheme(0, "auto"); + await testColorScheme(1, "auto"); + await testColorScheme(0, "light"); + await testColorScheme(1, "light"); + await testColorScheme(0, "dark"); + await testColorScheme(1, "dark"); + await testColorScheme(0, "sepia"); + await testColorScheme(1, "sepia"); +}); + +async function testCustomColors(aPref, color) { + // Set the theme selection to custom. + Services.prefs.setBoolPref("reader.colors_menu.enabled", true); + Services.prefs.setCharPref("reader.color_scheme", "custom"); + + // Set the custom pref to the color value. + Services.prefs.setCharPref(`reader.custom_colors.${aPref}`, color); + + // Open a browser tab, enter reader mode, and test if the page colors + // reflect the pref selection. + await BrowserTestUtils.withNewTab( + TEST_PATH + "readerModeArticle.html", + async function (browser) { + let pageShownPromise = BrowserTestUtils.waitForContentEvent( + browser, + "AboutReaderContentReady" + ); + + let readerButton = document.getElementById("reader-mode-button"); + readerButton.click(); + await pageShownPromise; + + let colorScheme = Services.prefs.getCharPref("reader.color_scheme"); + Assert.equal(colorScheme, "custom"); + let prefValue = Services.prefs.getStringPref( + `reader.custom_colors.${aPref}` + ); + let cssProp = `--custom-theme-${aPref}`; + + await SpecialPowers.spawn( + browser, + [prefValue, cssProp], + (customColor, prop) => { + let style = content.window.getComputedStyle(content.document.body); + let actualColor = style.getPropertyValue(prop); + Assert.equal(customColor, actualColor); + } + ); + } + ); +} + +/** + * Test that the custom color scheme selection updates the document colors correctly. + */ +add_task(async function () { + await testCustomColors("foreground", "#ffffff"); + await testCustomColors("background", "#000000"); + await testCustomColors("unvisited-links", "#ffffff"); + await testCustomColors("visited-links", "#ffffff"); + await testCustomColors("visited-links", "#ffffff"); + await testCustomColors("selection-highlight", "#ffffff"); +}); diff --git a/toolkit/components/reader/tests/browser/browser_readerMode_hidden_nodes.js b/toolkit/components/reader/tests/browser/browser_readerMode_hidden_nodes.js new file mode 100644 index 0000000000..a6d058dfb1 --- /dev/null +++ b/toolkit/components/reader/tests/browser/browser_readerMode_hidden_nodes.js @@ -0,0 +1,56 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/** + * Test that the reader mode button appears and works properly on + * reader-able content. + */ +const TEST_PREFS = [["reader.parse-on-load.enabled", true]]; + +const TEST_PATH = getRootDirectory(gTestPath).replace( + "chrome://mochitests/content", + "http://example.com" +); + +var readerButton = document.getElementById("reader-mode-button"); + +add_task(async function test_reader_button() { + registerCleanupFunction(function () { + // Reset test prefs. + TEST_PREFS.forEach(([name]) => { + Services.prefs.clearUserPref(name); + }); + while (gBrowser.tabs.length > 1) { + gBrowser.removeCurrentTab(); + } + }); + + // Set required test prefs. + TEST_PREFS.forEach(([name, value]) => { + Services.prefs.setBoolPref(name, value); + }); + + let tab = (gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser)); + is_element_hidden( + readerButton, + "Reader mode button is not present on a new tab" + ); + // Point tab to a test page that is not reader-able due to hidden nodes. + let url = TEST_PATH + "readerModeArticleHiddenNodes.html"; + let paintPromise = BrowserTestUtils.waitForContentEvent( + tab.linkedBrowser, + "MozAfterPaint", + false, + e => + e.originalTarget.location.href.endsWith("HiddenNodes.html") && + e.originalTarget.document.readyState == "complete" + ); + BrowserTestUtils.startLoadingURIString(tab.linkedBrowser, url); + await paintPromise; + + is_element_hidden( + readerButton, + "Reader mode button is still not present on tab with unreadable content." + ); +}); diff --git a/toolkit/components/reader/tests/browser/browser_readerMode_menu.js b/toolkit/components/reader/tests/browser/browser_readerMode_menu.js new file mode 100644 index 0000000000..2c08faf4f9 --- /dev/null +++ b/toolkit/components/reader/tests/browser/browser_readerMode_menu.js @@ -0,0 +1,75 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +const TEST_PATH = getRootDirectory(gTestPath).replace( + "chrome://mochitests/content", + "http://example.com" +); + +/** + * Test that the reader mode correctly calculates and displays the + * estimated reading time for a short article + */ +add_task(async function () { + await BrowserTestUtils.withNewTab( + TEST_PATH + "readerModeArticleShort.html", + async function (browser) { + let pageShownPromise = BrowserTestUtils.waitForContentEvent( + browser, + "AboutReaderContentReady" + ); + let readerButton = document.getElementById("reader-mode-button"); + readerButton.click(); + await pageShownPromise; + await SpecialPowers.spawn(browser, [], async function () { + function dispatchMouseEvent(win, target, eventName) { + let mouseEvent = new win.MouseEvent(eventName, { + view: win, + bubbles: true, + cancelable: true, + composed: true, + }); + target.dispatchEvent(mouseEvent); + } + + function simulateClick(target) { + dispatchMouseEvent(win, target, "mousedown"); + dispatchMouseEvent(win, target, "mouseup"); + dispatchMouseEvent(win, target, "click"); + } + + async function testOpenCloseDropdown(target) { + let button = doc.querySelector(`.${target}-button`); + + let dropdown = doc.querySelector(`.${target}-dropdown`); + ok(!dropdown.classList.contains("open"), "dropdown is closed"); + + simulateClick(button); + ok(dropdown.classList.contains("open"), "dropdown is open"); + + // simulate clicking on the article title to close the dropdown + let title = doc.querySelector(".reader-title"); + simulateClick(title); + ok(!dropdown.classList.contains("open"), "dropdown is closed"); + + // reopen the dropdown + simulateClick(button); + ok(dropdown.classList.contains("open"), "dropdown is open"); + + // now click on the button again to close it + simulateClick(button); + ok(!dropdown.classList.contains("open"), "dropdown is closed"); + } + + let doc = content.document; + let win = content.window; + + testOpenCloseDropdown("style"); + testOpenCloseDropdown("colors"); + }); + } + ); +}); diff --git a/toolkit/components/reader/tests/browser/browser_readerMode_pocket.js b/toolkit/components/reader/tests/browser/browser_readerMode_pocket.js new file mode 100644 index 0000000000..43426383ff --- /dev/null +++ b/toolkit/components/reader/tests/browser/browser_readerMode_pocket.js @@ -0,0 +1,136 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ +"use strict"; + +// This test verifies that the Save To Pocket button appears in reader mode, +// and is toggled hidden and visible when pocket is disabled and enabled. + +const TEST_PATH = getRootDirectory(gTestPath).replace( + "chrome://mochitests/content", + "http://example.com" +); + +async function getPocketButtonsCount(browser) { + return SpecialPowers.spawn(browser, [], () => { + return content.document.getElementsByClassName("pocket-button").length; + }); +} + +add_task(async function () { + // set the pocket preference before beginning. + await SpecialPowers.pushPrefEnv({ + set: [["extensions.pocket.enabled", true]], + }); + + var readerButton = document.getElementById("reader-mode-button"); + + let tab1 = await BrowserTestUtils.openNewForegroundTab( + gBrowser, + TEST_PATH + "readerModeArticleShort.html" + ); + + let promiseTabLoad = promiseTabLoadEvent(tab1); + readerButton.click(); + await promiseTabLoad; + + let tab2 = await BrowserTestUtils.openNewForegroundTab( + gBrowser, + TEST_PATH + "readerModeArticleMedium.html" + ); + + promiseTabLoad = promiseTabLoadEvent(tab2); + readerButton.click(); + await promiseTabLoad; + + is( + await getPocketButtonsCount(tab1.linkedBrowser), + 1, + "tab 1 has a pocket button" + ); + is( + await getPocketButtonsCount(tab1.linkedBrowser), + 1, + "tab 2 has a pocket button" + ); + + // Turn off the pocket preference. The Save To Pocket buttons should disappear. + await SpecialPowers.pushPrefEnv({ + set: [["extensions.pocket.enabled", false]], + }); + + is( + await getPocketButtonsCount(tab1.linkedBrowser), + 0, + "tab 1 has no pocket button" + ); + is( + await getPocketButtonsCount(tab1.linkedBrowser), + 0, + "tab 2 has no pocket button" + ); + + // Turn on the pocket preference. The Save To Pocket buttons should reappear again. + await SpecialPowers.pushPrefEnv({ + set: [["extensions.pocket.enabled", true]], + }); + + is( + await getPocketButtonsCount(tab1.linkedBrowser), + 1, + "tab 1 has a pocket button again" + ); + is( + await getPocketButtonsCount(tab1.linkedBrowser), + 1, + "tab 2 has a pocket button again" + ); + + BrowserTestUtils.removeTab(tab1); + BrowserTestUtils.removeTab(tab2); +}); + +/** + * Test that the pocket button toggles the pocket popup successfully + */ +add_task(async function () { + await BrowserTestUtils.withNewTab( + TEST_PATH + "readerModeArticleShort.html", + async function (browser) { + let pageShownPromise = BrowserTestUtils.waitForContentEvent( + browser, + "AboutReaderContentReady" + ); + let readerButton = document.getElementById("reader-mode-button"); + readerButton.click(); + await pageShownPromise; + + await SpecialPowers.spawn(browser, [], async function () { + content.document.querySelector(".pocket-button").click(); + }); + let panel = gBrowser.selectedBrowser.ownerDocument.querySelector( + "#customizationui-widget-panel" + ); + await BrowserTestUtils.waitForMutationCondition( + panel, + { attributes: true }, + () => { + return BrowserTestUtils.isVisible(panel); + } + ); + ok(BrowserTestUtils.isVisible(panel), "Panel buttons are visible"); + + await SpecialPowers.spawn(browser, [], async function () { + content.document.querySelector(".pocket-button").click(); + }); + await BrowserTestUtils.waitForMutationCondition( + panel, + { attributes: true }, + () => { + return BrowserTestUtils.isHidden(panel); + } + ); + + ok(BrowserTestUtils.isHidden(panel), "Panel buttons are hidden"); + } + ); +}); diff --git a/toolkit/components/reader/tests/browser/browser_readerMode_readingTime.js b/toolkit/components/reader/tests/browser/browser_readerMode_readingTime.js new file mode 100644 index 0000000000..91631b6234 --- /dev/null +++ b/toolkit/components/reader/tests/browser/browser_readerMode_readingTime.js @@ -0,0 +1,101 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +const TEST_PATH = getRootDirectory(gTestPath).replace( + "chrome://mochitests/content", + "http://example.com" +); + +/** + * Test that the reader mode correctly calculates and displays the + * estimated reading time for a normal length article + */ +add_task(async function () { + await BrowserTestUtils.withNewTab( + TEST_PATH + "readerModeArticle.html", + async function (browser) { + let pageShownPromise = BrowserTestUtils.waitForContentEvent( + browser, + "AboutReaderContentReady" + ); + let readerButton = document.getElementById("reader-mode-button"); + readerButton.click(); + await pageShownPromise; + await SpecialPowers.spawn(browser, [], async function () { + // make sure there is a reading time on the page and that it displays the correct information + let readingTimeElement = content.document.querySelector( + ".reader-estimated-time" + ); + ok(readingTimeElement, "Reading time element should be in document"); + const args = JSON.parse(readingTimeElement.dataset.l10nArgs); + is(args.rangePlural, "other", "Reading time should be '9-12 minutes'"); + ok( + /\b9\b.*\b12\b/.test(args.range), + "Reading time should be '9-12 minutes'" + ); + }); + } + ); +}); + +/** + * Test that the reader mode correctly calculates and displays the + * estimated reading time for a short article + */ +add_task(async function () { + await BrowserTestUtils.withNewTab( + TEST_PATH + "readerModeArticleShort.html", + async function (browser) { + let pageShownPromise = BrowserTestUtils.waitForContentEvent( + browser, + "AboutReaderContentReady" + ); + let readerButton = document.getElementById("reader-mode-button"); + readerButton.click(); + await pageShownPromise; + await SpecialPowers.spawn(browser, [], async function () { + // make sure there is a reading time on the page and that it displays the correct information + let readingTimeElement = content.document.querySelector( + ".reader-estimated-time" + ); + ok(readingTimeElement, "Reading time element should be in document"); + const args = JSON.parse(readingTimeElement.dataset.l10nArgs); + is(args.rangePlural, "one", "Reading time should be '~1 minute'"); + ok(/\b1\b/.test(args.range), "Reading time should be '~1 minute'"); + }); + } + ); +}); + +/** + * Test that the reader mode correctly calculates and displays the + * estimated reading time for a medium article where a single number + * is displayed. + */ +add_task(async function () { + await BrowserTestUtils.withNewTab( + TEST_PATH + "readerModeArticleMedium.html", + async function (browser) { + let pageShownPromise = BrowserTestUtils.waitForContentEvent( + browser, + "AboutReaderContentReady" + ); + let readerButton = document.getElementById("reader-mode-button"); + readerButton.click(); + await pageShownPromise; + await SpecialPowers.spawn(browser, [], async function () { + // make sure there is a reading time on the page and that it displays the correct information + let readingTimeElement = content.document.querySelector( + ".reader-estimated-time" + ); + ok(readingTimeElement, "Reading time element should be in document"); + const args = JSON.parse(readingTimeElement.dataset.l10nArgs); + is(args.rangePlural, "other", "Reading time should be '~3 minutes'"); + ok(/\b3\b/.test(args.range), "Reading time should be '~3 minutes'"); + }); + } + ); +}); diff --git a/toolkit/components/reader/tests/browser/browser_readerMode_refresh.js b/toolkit/components/reader/tests/browser/browser_readerMode_refresh.js new file mode 100644 index 0000000000..00b4557f70 --- /dev/null +++ b/toolkit/components/reader/tests/browser/browser_readerMode_refresh.js @@ -0,0 +1,49 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +const TEST_PATH = getRootDirectory(gTestPath).replace( + "chrome://mochitests/content", + "http://example.com" +); + +async function testRefresh(url) { + // Open an article in a browser tab + await BrowserTestUtils.withNewTab(url, async function (browser) { + let pageShownPromise = BrowserTestUtils.waitForContentEvent( + browser, + "AboutReaderContentReady" + ); + + let readerButton = document.getElementById("reader-mode-button"); + let refreshButton = document.getElementById("reload-button"); + + // Enter Reader Mode + readerButton.click(); + await pageShownPromise; + + // Refresh the page + pageShownPromise = BrowserTestUtils.waitForContentEvent( + browser, + "AboutReaderContentReady" + ); + refreshButton.click(); + await pageShownPromise; + await SpecialPowers.spawn(browser, [], () => { + ok( + !content.document.documentElement.hasAttribute("data-is-error"), + "The data-is-error attribute is present when Reader Mode failed to load an article." + ); + }); + }); +} + +add_task(async function () { + // Testing a non-text/plain document + await testRefresh(TEST_PATH + "readerModeArticle.html"); + + // Testing a test/plain document + await testRefresh(TEST_PATH + "readerModeArticleTextPlain.txt"); +}); diff --git a/toolkit/components/reader/tests/browser/browser_readerMode_remoteType.js b/toolkit/components/reader/tests/browser/browser_readerMode_remoteType.js new file mode 100644 index 0000000000..c2510667c8 --- /dev/null +++ b/toolkit/components/reader/tests/browser/browser_readerMode_remoteType.js @@ -0,0 +1,87 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +const TEST_PATH = getRootDirectory(gTestPath).replace( + "chrome://mochitests/content", + "http://example.com" +); + +const CROSS_SITE_TEST_PATH = getRootDirectory(gTestPath).replace( + "chrome://mochitests/content", + "http://example.org" +); + +/** + * Test that switching an article into readermode doesn't change its' remoteType. + * Test that the reader mode correctly calculates and displays the + * estimated reading time for a short article + */ +add_task(async function () { + info("opening readermode normally to ensure process doesn't change"); + let articleRemoteType; + let aboutReaderURL; + await BrowserTestUtils.withNewTab( + TEST_PATH + "readerModeArticleShort.html", + async function (browser) { + articleRemoteType = browser.remoteType; + + // Click on the readermode button to switch into reader mode, and get the + // URL for that reader mode. + let pageShownPromise = BrowserTestUtils.waitForContentEvent( + browser, + "AboutReaderContentReady" + ); + let readerButton = document.getElementById("reader-mode-button"); + readerButton.click(); + await pageShownPromise; + + aboutReaderURL = browser.documentURI.spec; + ok( + aboutReaderURL.startsWith("about:reader"), + "about:reader should have been opened" + ); + is( + browser.remoteType, + articleRemoteType, + "remote type should not have changed" + ); + } + ); + + info( + "opening new tab directly with about reader URL into correct remote type" + ); + await BrowserTestUtils.withNewTab(aboutReaderURL, async function (browser) { + is( + browser.remoteType, + articleRemoteType, + "Should have performed about:reader load in the correct remote type" + ); + }); + + info("navigating process into correct remote type"); + await BrowserTestUtils.withNewTab( + CROSS_SITE_TEST_PATH + "readerModeArticleShort.html", + async function (browser) { + if (SpecialPowers.useRemoteSubframes) { + isnot( + browser.remoteType, + articleRemoteType, + "Cross-site article should have different remote type with fission" + ); + } + + BrowserTestUtils.startLoadingURIString(browser, aboutReaderURL); + await BrowserTestUtils.browserLoaded(browser); + + is( + browser.remoteType, + articleRemoteType, + "Should have switched into the correct remote type" + ); + } + ); +}); diff --git a/toolkit/components/reader/tests/browser/browser_readerMode_samesite_cookie_redirect.js b/toolkit/components/reader/tests/browser/browser_readerMode_samesite_cookie_redirect.js new file mode 100644 index 0000000000..22703b9a81 --- /dev/null +++ b/toolkit/components/reader/tests/browser/browser_readerMode_samesite_cookie_redirect.js @@ -0,0 +1,52 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const TEST_ORIGIN = getRootDirectory(gTestPath).replace( + "chrome://mochitests/content", + "http://example.com" +); + +const { HttpServer } = ChromeUtils.importESModule( + "resource://testing-common/httpd.sys.mjs" +); + +add_task(async function test_ss_cookie_redirect() { + // Set the samesite cookie + let tab = await BrowserTestUtils.openNewForegroundTab( + gBrowser, + TEST_ORIGIN + "setSameSiteCookie.html" + ); + BrowserTestUtils.removeTab(tab); + + let server = new HttpServer(); + server.start(-1); + server.registerPathHandler("/foo", (request, response) => { + response.setStatusLine(request.httpVersion, 302, "Found"); + response.setHeader("Location", TEST_ORIGIN + "getCookies.sjs"); + }); + registerCleanupFunction(() => server.stop()); + const { primaryPort, primaryHost } = server.identity; + const serverURL = `http://${primaryHost}:${primaryPort}/foo`; + + // Now open `getCookies.sjs` but via a redirect: + await BrowserTestUtils.withNewTab("about:blank", async browser => { + let loaded = BrowserTestUtils.waitForContentEvent( + browser, + "AboutReaderContentReady" + ); + BrowserTestUtils.startLoadingURIString( + browser, + "about:reader?url=" + encodeURIComponent(serverURL) + ); + await loaded; + await SpecialPowers.spawn(browser, [], () => { + is( + content.document.getElementById("cookieSpan").textContent, + "", + "Shouldn't get cookies." + ); + }); + }); +}); diff --git a/toolkit/components/reader/tests/browser/browser_readerMode_with_anchor.js b/toolkit/components/reader/tests/browser/browser_readerMode_with_anchor.js new file mode 100644 index 0000000000..229daaed9d --- /dev/null +++ b/toolkit/components/reader/tests/browser/browser_readerMode_with_anchor.js @@ -0,0 +1,89 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +const TEST_PATH = getRootDirectory(gTestPath).replace( + "chrome://mochitests/content", + "http://example.com" +); + +add_task(async function test_loading_withHash() { + await BrowserTestUtils.withNewTab( + TEST_PATH + "readerModeArticle.html#foo", + async function (browser) { + let pageShownPromise = BrowserTestUtils.waitForContentEvent( + browser, + "AboutReaderContentReady" + ); + let readerButton = document.getElementById("reader-mode-button"); + readerButton.click(); + await pageShownPromise; + await SpecialPowers.spawn(browser, [], async function () { + let foo = content.document.getElementById("foo"); + ok(foo, "foo element should be in document"); + let { scrollTop } = content.document.documentElement; + if (scrollTop == 0) { + await ContentTaskUtils.waitForEvent(content.document, "scroll"); + ({ scrollTop } = content.document.documentElement); + } + let { offsetTop } = foo; + Assert.lessOrEqual( + Math.abs(scrollTop - offsetTop), + 1, + `scrollTop (${scrollTop}) should be within 1 CSS pixel of offsetTop (${offsetTop})` + ); + }); + } + ); +}); + +add_task(async function test_loading_withoutHash() { + await BrowserTestUtils.withNewTab( + TEST_PATH + "readerModeArticle.html", + async function (browser) { + let pageShownPromise = BrowserTestUtils.waitForContentEvent( + browser, + "AboutReaderContentReady" + ); + let pageLoadedPromise = BrowserTestUtils.waitForContentEvent( + browser, + "load", + true + ); + let readerButton = document.getElementById("reader-mode-button"); + readerButton.click(); + await Promise.all([pageShownPromise, pageLoadedPromise]); + await SpecialPowers.spawn(gBrowser.selectedBrowser, [], async () => { + Assert.equal( + content.document.documentElement.scrollTop, + 0, + "scrollTop should be 0" + ); + }); + let scrollEventPromise = BrowserTestUtils.waitForContentEvent( + browser, + "scroll", + true + ); + await BrowserTestUtils.synthesizeMouseAtCenter( + "#foo-anchor", + {}, + browser + ); + await scrollEventPromise; + await SpecialPowers.spawn(browser, [], async function () { + let foo = content.document.getElementById("foo"); + ok(foo, "foo element should be in document"); + let { scrollTop } = content.document.documentElement; + let { offsetTop } = foo; + Assert.lessOrEqual( + Math.abs(scrollTop - offsetTop), + 1, + `scrollTop (${scrollTop}) should be within 1 CSS pixel of offsetTop (${offsetTop})` + ); + }); + } + ); +}); diff --git a/toolkit/components/reader/tests/browser/getCookies.sjs b/toolkit/components/reader/tests/browser/getCookies.sjs new file mode 100644 index 0000000000..02e29fd877 --- /dev/null +++ b/toolkit/components/reader/tests/browser/getCookies.sjs @@ -0,0 +1,16 @@ +function handleRequest(request, response) { + const cookies = request.hasHeader("Cookie") + ? request.getHeader("Cookie") + : ""; + response.write(` + + + + + + +

Cookie: ${cookies}

+ + + `); +} diff --git a/toolkit/components/reader/tests/browser/head.js b/toolkit/components/reader/tests/browser/head.js new file mode 100644 index 0000000000..5f9baf8fcd --- /dev/null +++ b/toolkit/components/reader/tests/browser/head.js @@ -0,0 +1,59 @@ +/* exported promiseTabLoadEvent, is_element_visible, is_element_hidden */ + +/** + * Waits for a load (or custom) event to finish in a given tab. If provided + * load an uri into the tab. + * + * @param tab + * The tab to load into. + * @param [optional] url + * The url to load, or the current url. + * @return {Promise} resolved when the event is handled. + * @resolves to the received event + * @rejects if a valid load event is not received within a meaningful interval + */ +function promiseTabLoadEvent(tab, url) { + let deferred = Promise.withResolvers(); + info("Wait tab event: load"); + + function handle(loadedUrl) { + if (loadedUrl === "about:blank" || (url && loadedUrl !== url)) { + info(`Skipping spurious load event for ${loadedUrl}`); + return false; + } + + info("Tab event received: load"); + return true; + } + + // Create two promises: one resolved from the content process when the page + // loads and one that is rejected if we take too long to load the url. + let loaded = BrowserTestUtils.browserLoaded(tab.linkedBrowser, false, handle); + + let timeout = setTimeout(() => { + deferred.reject(new Error("Timed out while waiting for a 'load' event")); + }, 30000); + + loaded.then(() => { + clearTimeout(timeout); + deferred.resolve(); + }); + + if (url) { + BrowserTestUtils.startLoadingURIString(tab.linkedBrowser, url); + } + + // Promise.all rejects if either promise rejects (i.e. if we time out) and + // if our loaded promise resolves before the timeout, then we resolve the + // timeout promise as well, causing the all promise to resolve. + return Promise.all([deferred.promise, loaded]); +} + +function is_element_visible(element, msg) { + isnot(element, null, "Element should not be null, when checking visibility"); + ok(BrowserTestUtils.isVisible(element), msg || "Element should be visible"); +} +function is_element_hidden(element, msg) { + isnot(element, null, "Element should not be null, when checking visibility"); + ok(BrowserTestUtils.isHidden(element), msg || "Element should be hidden"); +} diff --git a/toolkit/components/reader/tests/browser/linkToGetCookies.html b/toolkit/components/reader/tests/browser/linkToGetCookies.html new file mode 100644 index 0000000000..a05d32af4e --- /dev/null +++ b/toolkit/components/reader/tests/browser/linkToGetCookies.html @@ -0,0 +1,13 @@ + + + + + + +
+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ut gravida lorem. Ut turpis felis, pulvinar a semper sed, adipiscing id dolor. Pellentesque auctor nisi id magna consequat sagittis. Curabitur dapibus enim sit amet elit pharetra tincidunt feugiat nisl imperdiet. Ut convallis libero in urna ultrices accumsan. Donec sed odio eros. Donec viverra mi quis quam pulvinar at malesuada arcu rhoncus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In rutrum accumsan ultricies. Mauris vitae nisi at sem facilisis semper ac in est.

+ +

Cross-origin link to getCookies.html

+
+ + diff --git a/toolkit/components/reader/tests/browser/readerModeArticle.html b/toolkit/components/reader/tests/browser/readerModeArticle.html new file mode 100644 index 0000000000..a0f1c64da0 --- /dev/null +++ b/toolkit/components/reader/tests/browser/readerModeArticle.html @@ -0,0 +1,28 @@ + + + +Article title + + + +
Site header
+
+

Article title

+ +

by Jane Doe

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ut gravida lorem. Ut turpis felis, pulvinar a semper sed, adipiscing id dolor. Pellentesque auctor nisi id magna consequat sagittis. Curabitur dapibus enim sit amet elit pharetra tincidunt feugiat nisl imperdiet. Ut convallis libero in urna ultrices accumsan. Donec sed odio eros. Donec viverra mi quis quam pulvinar at malesuada arcu rhoncus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In rutrum accumsan ultricies. Mauris vitae nisi at sem facilisis semper ac in est.

+

Vivamus fermentum semper porta. Nunc diam velit, adipiscing ut tristique vitae, sagittis vel odio. Maecenas convallis ullamcorper ultricies. Curabitur ornare, ligula semper consectetur sagittis, nisi diam iaculis velit, id fringilla sem nunc vel mi. Nam dictum, odio nec pretium volutpat, arcu ante placerat erat, non tristique elit urna et turpis. Quisque mi metus, ornare sit amet fermentum et, tincidunt et orci. Fusce eget orci a orci congue vestibulum. Ut dolor diam, elementum et vestibulum eu, porttitor vel elit. Curabitur venenatis pulvinar tellus gravida ornare. Sed et erat faucibus nunc euismod ultricies ut id justo. Nullam cursus suscipit nisi, et ultrices justo sodales nec. Fusce venenatis facilisis lectus ac semper. Aliquam at massa ipsum. Quisque bibendum purus convallis nulla ultrices ultricies. Nullam aliquam, mi eu aliquam tincidunt, purus velit laoreet tortor, viverra pretium nisi quam vitae mi. Fusce vel volutpat elit. Nam sagittis nisi dui.

+

Vivamus fermentum semper porta. Nunc diam velit, adipiscing ut tristique vitae, sagittis vel odio. Maecenas convallis ullamcorper ultricies. Curabitur ornare, ligula semper consectetur sagittis, nisi diam iaculis velit, id fringilla sem nunc vel mi. Nam dictum, odio nec pretium volutpat, arcu ante placerat erat, non tristique elit urna et turpis. Quisque mi metus, ornare sit amet fermentum et, tincidunt et orci. Fusce eget orci a orci congue vestibulum. Ut dolor diam, elementum et vestibulum eu, porttitor vel elit. Curabitur venenatis pulvinar tellus gravida ornare. Sed et erat faucibus nunc euismod ultricies ut id justo. Nullam cursus suscipit nisi, et ultrices justo sodales nec. Fusce venenatis facilisis lectus ac semper. Aliquam at massa ipsum. Quisque bibendum purus convallis nulla ultrices ultricies. Nullam aliquam, mi eu aliquam tincidunt, purus velit laoreet tortor, viverra pretium nisi quam vitae mi. Fusce vel volutpat elit. Nam sagittis nisi dui.

+

Vivamus fermentum semper porta. Nunc diam velit, adipiscing ut tristique vitae, sagittis vel odio. Maecenas convallis ullamcorper ultricies. Curabitur ornare, ligula semper consectetur sagittis, nisi diam iaculis velit, id fringilla sem nunc vel mi. Nam dictum, odio nec pretium volutpat, arcu ante placerat erat, non tristique elit urna et turpis. Quisque mi metus, ornare sit amet fermentum et, tincidunt et orci. Fusce eget orci a orci congue vestibulum. Ut dolor diam, elementum et vestibulum eu, porttitor vel elit. Curabitur venenatis pulvinar tellus gravida ornare. Sed et erat faucibus nunc euismod ultricies ut id justo. Nullam cursus suscipit nisi, et ultrices justo sodales nec. Fusce venenatis facilisis lectus ac semper. Aliquam at massa ipsum. Quisque bibendum purus convallis nulla ultrices ultricies. Nullam aliquam, mi eu aliquam tincidunt, purus velit laoreet tortor, viverra pretium nisi quam vitae mi. Fusce vel volutpat elit. Nam sagittis nisi dui.

+

Vivamus fermentum semper porta. Nunc diam velit, adipiscing ut tristique vitae, sagittis vel odio. Maecenas convallis ullamcorper ultricies. Curabitur ornare, ligula semper consectetur sagittis, nisi diam iaculis velit, id fringilla sem nunc vel mi. Nam dictum, odio nec pretium volutpat, arcu ante placerat erat, non tristique elit urna et turpis. Quisque mi metus, ornare sit amet fermentum et, tincidunt et orci. Fusce eget orci a orci congue vestibulum. Ut dolor diam, elementum et vestibulum eu, porttitor vel elit. Curabitur venenatis pulvinar tellus gravida ornare. Sed et erat faucibus nunc euismod ultricies ut id justo. Nullam cursus suscipit nisi, et ultrices justo sodales nec. Fusce venenatis facilisis lectus ac semper. Aliquam at massa ipsum. Quisque bibendum purus convallis nulla ultrices ultricies. Nullam aliquam, mi eu aliquam tincidunt, purus velit laoreet tortor, viverra pretium nisi quam vitae mi. Fusce vel volutpat elit. Nam sagittis nisi dui.

+

by John Doe

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ut gravida lorem. Ut turpis felis, pulvinar a semper sed, adipiscing id dolor. Pellentesque auctor nisi id magna consequat sagittis. Curabitur dapibus enim sit amet elit pharetra tincidunt feugiat nisl imperdiet. Ut convallis libero in urna ultrices accumsan. Donec sed odio eros. Donec viverra mi quis quam pulvinar at malesuada arcu rhoncus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In rutrum accumsan ultricies. Mauris vitae nisi at sem facilisis semper ac in est.

+

Vivamus fermentum semper porta. Nunc diam velit, adipiscing ut tristique vitae, sagittis vel odio. Maecenas convallis ullamcorper ultricies. Curabitur ornare, ligula semper consectetur sagittis, nisi diam iaculis velit, id fringilla sem nunc vel mi. Nam dictum, odio nec pretium volutpat, arcu ante placerat erat, non tristique elit urna et turpis. Quisque mi metus, ornare sit amet fermentum et, tincidunt et orci. Fusce eget orci a orci congue vestibulum. Ut dolor diam, elementum et vestibulum eu, porttitor vel elit. Curabitur venenatis pulvinar tellus gravida ornare. Sed et erat faucibus nunc euismod ultricies ut id justo. Nullam cursus suscipit nisi, et ultrices justo sodales nec. Fusce venenatis facilisis lectus ac semper. Aliquam at massa ipsum. Quisque bibendum purus convallis nulla ultrices ultricies. Nullam aliquam, mi eu aliquam tincidunt, purus velit laoreet tortor, viverra pretium nisi quam vitae mi. Fusce vel volutpat elit. Nam sagittis nisi dui.

+

Vivamus fermentum semper porta. Nunc diam velit, adipiscing ut tristique vitae, sagittis vel odio. Maecenas convallis ullamcorper ultricies. Curabitur ornare, ligula semper consectetur sagittis, nisi diam iaculis velit, id fringilla sem nunc vel mi. Nam dictum, odio nec pretium volutpat, arcu ante placerat erat, non tristique elit urna et turpis. Quisque mi metus, ornare sit amet fermentum et, tincidunt et orci. Fusce eget orci a orci congue vestibulum. Ut dolor diam, elementum et vestibulum eu, porttitor vel elit. Curabitur venenatis pulvinar tellus gravida ornare. Sed et erat faucibus nunc euismod ultricies ut id justo. Nullam cursus suscipit nisi, et ultrices justo sodales nec. Fusce venenatis facilisis lectus ac semper. Aliquam at massa ipsum. Quisque bibendum purus convallis nulla ultrices ultricies. Nullam aliquam, mi eu aliquam tincidunt, purus velit laoreet tortor, viverra pretium nisi quam vitae mi. Fusce vel volutpat elit. Nam sagittis nisi dui.

+

Vivamus fermentum semper porta. Nunc diam velit, adipiscing ut tristique vitae, sagittis vel odio. Maecenas convallis ullamcorper ultricies. Curabitur ornare, ligula semper consectetur sagittis, nisi diam iaculis velit, id fringilla sem nunc vel mi. Nam dictum, odio nec pretium volutpat, arcu ante placerat erat, non tristique elit urna et turpis. Quisque mi metus, ornare sit amet fermentum et, tincidunt et orci. Fusce eget orci a orci congue vestibulum. Ut dolor diam, elementum et vestibulum eu, porttitor vel elit. Curabitur venenatis pulvinar tellus gravida ornare. Sed et erat faucibus nunc euismod ultricies ut id justo. Nullam cursus suscipit nisi, et ultrices justo sodales nec. Fusce venenatis facilisis lectus ac semper. Aliquam at massa ipsum. Quisque bibendum purus convallis nulla ultrices ultricies. Nullam aliquam, mi eu aliquam tincidunt, purus velit laoreet tortor, viverra pretium nisi quam vitae mi. Fusce vel volutpat elit. Nam sagittis nisi dui.

+

Vivamus fermentum semper porta. Nunc diam velit, adipiscing ut tristique vitae, sagittis vel odio. Maecenas convallis ullamcorper ultricies. Curabitur ornare, ligula semper consectetur sagittis, nisi diam iaculis velit, id fringilla sem nunc vel mi. Nam dictum, odio nec pretium volutpat, arcu ante placerat erat, non tristique elit urna et turpis. Quisque mi metus, ornare sit amet fermentum et, tincidunt et orci. Fusce eget orci a orci congue vestibulum. Ut dolor diam, elementum et vestibulum eu, porttitor vel elit. Curabitur venenatis pulvinar tellus gravida ornare. Sed et erat faucibus nunc euismod ultricies ut id justo. Nullam cursus suscipit nisi, et ultrices justo sodales nec. Fusce venenatis facilisis lectus ac semper. Aliquam at massa ipsum. Quisque bibendum purus convallis nulla ultrices ultricies. Nullam aliquam, mi eu aliquam tincidunt, purus velit laoreet tortor, viverra pretium nisi quam vitae mi. Fusce vel volutpat elit. Nam sagittis nisi dui.

+
+ + diff --git a/toolkit/components/reader/tests/browser/readerModeArticleContainsLink.html b/toolkit/components/reader/tests/browser/readerModeArticleContainsLink.html new file mode 100644 index 0000000000..be2d7d6469 --- /dev/null +++ b/toolkit/components/reader/tests/browser/readerModeArticleContainsLink.html @@ -0,0 +1,20 @@ + + + +Article title + + + +
Site header
+
+

Article title

+

by Jane Doe

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ut gravida lorem. Ut turpis felis, pulvinar a semper sed, adipiscing id dolor. Pellentesque auctor nisi id magna consequat sagittis. Curabitur dapibus enim sit amet elit pharetra tincidunt feugiat nisl imperdiet. Ut convallis libero in urna ultrices accumsan. Donec sed odio eros. Donec viverra mi quis quam pulvinar at malesuada arcu rhoncus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In rutrum accumsan ultricies. Mauris vitae nisi at sem facilisis semper ac in est.

+

Vivamus fermentum semper porta. Nunc diam velit, adipiscing ut tristique vitae, sagittis vel odio. Maecenas convallis ullamcorper ultricies. Curabitur ornare, ligula semper consectetur sagittis, nisi diam iaculis velit, id fringilla sem nunc vel mi. Nam dictum, odio nec pretium volutpat, arcu ante placerat erat, non tristique elit urna et turpis. Quisque mi metus, ornare sit amet fermentum et, tincidunt et orci. Fusce eget orci a orci congue vestibulum. Ut dolor diam, elementum et vestibulum eu, porttitor vel elit. Curabitur venenatis pulvinar tellus gravida ornare. Sed et erat faucibus nunc euismod ultricies ut id justo. Nullam cursus suscipit nisi, et ultrices justo sodales nec. Fusce venenatis facilisis lectus ac semper. Aliquam at massa ipsum. Quisque bibendum purus convallis nulla ultrices ultricies. Nullam aliquam, mi eu aliquam tincidunt, purus velit laoreet tortor, viverra pretium nisi quam vitae mi. Fusce vel volutpat elit. Nam sagittis nisi dui.

+

Vivamus fermentum semper porta. Nunc diam velit, adipiscing ut tristique vitae, sagittis vel odio. Maecenas convallis ullamcorper ultricies. Curabitur ornare, ligula semper consectetur sagittis, nisi diam iaculis velit, id fringilla sem nunc vel mi. Nam dictum, odio nec pretium volutpat, arcu ante placerat erat, non tristique elit urna et turpis. Quisque mi metus, ornare sit amet fermentum et, tincidunt et orci. Fusce eget orci a orci congue vestibulum. Ut dolor diam, elementum et vestibulum eu, porttitor vel elit. Curabitur venenatis pulvinar tellus gravida ornare. Sed et erat faucibus nunc euismod ultricies ut id justo. Nullam cursus suscipit nisi, et ultrices justo sodales nec. Fusce venenatis facilisis lectus ac semper. Aliquam at massa ipsum. Quisque bibendum purus convallis nulla ultrices ultricies. Nullam aliquam, mi eu aliquam tincidunt, purus velit laoreet tortor, viverra pretium nisi quam vitae mi. Fusce vel volutpat elit. Nam sagittis nisi dui.

+

Link to another page.

+

Vivamus fermentum semper porta. Nunc diam velit, adipiscing ut tristique vitae, sagittis vel odio. Maecenas convallis ullamcorper ultricies. Curabitur ornare, ligula semper consectetur sagittis, nisi diam iaculis velit, id fringilla sem nunc vel mi. Nam dictum, odio nec pretium volutpat, arcu ante placerat erat, non tristique elit urna et turpis. Quisque mi metus, ornare sit amet fermentum et, tincidunt et orci. Fusce eget orci a orci congue vestibulum. Ut dolor diam, elementum et vestibulum eu, porttitor vel elit. Curabitur venenatis pulvinar tellus gravida ornare. Sed et erat faucibus nunc euismod ultricies ut id justo. Nullam cursus suscipit nisi, et ultrices justo sodales nec. Fusce venenatis facilisis lectus ac semper. Aliquam at massa ipsum. Quisque bibendum purus convallis nulla ultrices ultricies. Nullam aliquam, mi eu aliquam tincidunt, purus velit laoreet tortor, viverra pretium nisi quam vitae mi. Fusce vel volutpat elit. Nam sagittis nisi dui.

+

Vivamus fermentum semper porta. Nunc diam velit, adipiscing ut tristique vitae, sagittis vel odio. Maecenas convallis ullamcorper ultricies. Curabitur ornare, ligula semper consectetur sagittis, nisi diam iaculis velit, id fringilla sem nunc vel mi. Nam dictum, odio nec pretium volutpat, arcu ante placerat erat, non tristique elit urna et turpis. Quisque mi metus, ornare sit amet fermentum et, tincidunt et orci. Fusce eget orci a orci congue vestibulum. Ut dolor diam, elementum et vestibulum eu, porttitor vel elit. Curabitur venenatis pulvinar tellus gravida ornare. Sed et erat faucibus nunc euismod ultricies ut id justo. Nullam cursus suscipit nisi, et ultrices justo sodales nec. Fusce venenatis facilisis lectus ac semper. Aliquam at massa ipsum. Quisque bibendum purus convallis nulla ultrices ultricies. Nullam aliquam, mi eu aliquam tincidunt, purus velit laoreet tortor, viverra pretium nisi quam vitae mi. Fusce vel volutpat elit. Nam sagittis nisi dui.

+
+ + diff --git a/toolkit/components/reader/tests/browser/readerModeArticleHiddenNodes.html b/toolkit/components/reader/tests/browser/readerModeArticleHiddenNodes.html new file mode 100644 index 0000000000..92441b7978 --- /dev/null +++ b/toolkit/components/reader/tests/browser/readerModeArticleHiddenNodes.html @@ -0,0 +1,22 @@ + + + +Article title + + + + +
Site header
+
+

Article title

+

by Jane Doe

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ut gravida lorem. Ut turpis felis, pulvinar a semper sed, adipiscing id dolor. Pellentesque auctor nisi id magna consequat sagittis. Curabitur dapibus enim sit amet elit pharetra tincidunt feugiat nisl imperdiet. Ut convallis libero in urna ultrices accumsan. Donec sed odio eros. Donec viverra mi quis quam pulvinar at malesuada arcu rhoncus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In rutrum accumsan ultricies. Mauris vitae nisi at sem facilisis semper ac in est.

+

Vivamus fermentum semper porta. Nunc diam velit, adipiscing ut tristique vitae, sagittis vel odio. Maecenas convallis ullamcorper ultricies. Curabitur ornare, ligula semper consectetur sagittis, nisi diam iaculis velit, id fringilla sem nunc vel mi. Nam dictum, odio nec pretium volutpat, arcu ante placerat erat, non tristique elit urna et turpis. Quisque mi metus, ornare sit amet fermentum et, tincidunt et orci. Fusce eget orci a orci congue vestibulum. Ut dolor diam, elementum et vestibulum eu, porttitor vel elit. Curabitur venenatis pulvinar tellus gravida ornare. Sed et erat faucibus nunc euismod ultricies ut id justo. Nullam cursus suscipit nisi, et ultrices justo sodales nec. Fusce venenatis facilisis lectus ac semper. Aliquam at massa ipsum. Quisque bibendum purus convallis nulla ultrices ultricies. Nullam aliquam, mi eu aliquam tincidunt, purus velit laoreet tortor, viverra pretium nisi quam vitae mi. Fusce vel volutpat elit. Nam sagittis nisi dui.

+

Vivamus fermentum semper porta. Nunc diam velit, adipiscing ut tristique vitae, sagittis vel odio. Maecenas convallis ullamcorper ultricies. Curabitur ornare, ligula semper consectetur sagittis, nisi diam iaculis velit, id fringilla sem nunc vel mi. Nam dictum, odio nec pretium volutpat, arcu ante placerat erat, non tristique elit urna et turpis. Quisque mi metus, ornare sit amet fermentum et, tincidunt et orci. Fusce eget orci a orci congue vestibulum. Ut dolor diam, elementum et vestibulum eu, porttitor vel elit. Curabitur venenatis pulvinar tellus gravida ornare. Sed et erat faucibus nunc euismod ultricies ut id justo. Nullam cursus suscipit nisi, et ultrices justo sodales nec. Fusce venenatis facilisis lectus ac semper. Aliquam at massa ipsum. Quisque bibendum purus convallis nulla ultrices ultricies. Nullam aliquam, mi eu aliquam tincidunt, purus velit laoreet tortor, viverra pretium nisi quam vitae mi. Fusce vel volutpat elit. Nam sagittis nisi dui.

+

Vivamus fermentum semper porta. Nunc diam velit, adipiscing ut tristique vitae, sagittis vel odio. Maecenas convallis ullamcorper ultricies. Curabitur ornare, ligula semper consectetur sagittis, nisi diam iaculis velit, id fringilla sem nunc vel mi. Nam dictum, odio nec pretium volutpat, arcu ante placerat erat, non tristique elit urna et turpis. Quisque mi metus, ornare sit amet fermentum et, tincidunt et orci. Fusce eget orci a orci congue vestibulum. Ut dolor diam, elementum et vestibulum eu, porttitor vel elit. Curabitur venenatis pulvinar tellus gravida ornare. Sed et erat faucibus nunc euismod ultricies ut id justo. Nullam cursus suscipit nisi, et ultrices justo sodales nec. Fusce venenatis facilisis lectus ac semper. Aliquam at massa ipsum. Quisque bibendum purus convallis nulla ultrices ultricies. Nullam aliquam, mi eu aliquam tincidunt, purus velit laoreet tortor, viverra pretium nisi quam vitae mi. Fusce vel volutpat elit. Nam sagittis nisi dui.

+

Vivamus fermentum semper porta. Nunc diam velit, adipiscing ut tristique vitae, sagittis vel odio. Maecenas convallis ullamcorper ultricies. Curabitur ornare, ligula semper consectetur sagittis, nisi diam iaculis velit, id fringilla sem nunc vel mi. Nam dictum, odio nec pretium volutpat, arcu ante placerat erat, non tristique elit urna et turpis. Quisque mi metus, ornare sit amet fermentum et, tincidunt et orci. Fusce eget orci a orci congue vestibulum. Ut dolor diam, elementum et vestibulum eu, porttitor vel elit. Curabitur venenatis pulvinar tellus gravida ornare. Sed et erat faucibus nunc euismod ultricies ut id justo. Nullam cursus suscipit nisi, et ultrices justo sodales nec. Fusce venenatis facilisis lectus ac semper. Aliquam at massa ipsum. Quisque bibendum purus convallis nulla ultrices ultricies. Nullam aliquam, mi eu aliquam tincidunt, purus velit laoreet tortor, viverra pretium nisi quam vitae mi. Fusce vel volutpat elit. Nam sagittis nisi dui.

+
+ + diff --git a/toolkit/components/reader/tests/browser/readerModeArticleMedium.html b/toolkit/components/reader/tests/browser/readerModeArticleMedium.html new file mode 100644 index 0000000000..70b172cf63 --- /dev/null +++ b/toolkit/components/reader/tests/browser/readerModeArticleMedium.html @@ -0,0 +1,16 @@ + + + +Article title + + + +
Site header
+
+

Article title

+

by Jane Doe

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ut gravida lorem. Ut turpis felis, pulvinar a semper sed, adipiscing id dolor. Pellentesque auctor nisi id magna consequat sagittis. Curabitur dapibus enim sit amet elit pharetra tincidunt feugiat nisl imperdiet. Ut convallis libero in urna ultrices accumsan. Donec sed odio eros. Donec viverra mi quis quam pulvinar at malesuada arcu rhoncus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetu

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ut gravida lorem. Ut turpis felis, pulvinar a semper sed, adipiscing id dolor. Pellentesque auctor nisi id magna consequat sagittis. Curabitur dapibus enim sit amet elit pharetra tincidunt feugiat nisl imperdiet. Ut convallis libero in urna ultrices accumsan. Donec sed odio eros. Donec viverra mi quis quam pulvinar at malesuada arcu rhoncus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetu

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ut gravida lorem. Ut turpis felis, pulvinar a semper sed, adipiscing id dolor. Pellentesque auctor nisi id magna consequat sagittis. Curabitur dapibus enim sit amet elit pharetra tincidunt feugiat nisl imperdiet. Ut convallis libero in urna ultrices accumsan. Donec sed odio eros. Donec viverra mi quis quam pulvinar at malesuada arcu rhoncus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetu

+ + diff --git a/toolkit/components/reader/tests/browser/readerModeArticleShort.html b/toolkit/components/reader/tests/browser/readerModeArticleShort.html new file mode 100644 index 0000000000..692471f27f --- /dev/null +++ b/toolkit/components/reader/tests/browser/readerModeArticleShort.html @@ -0,0 +1,14 @@ + + + +Article title + + + +
Site header
+
+

Article title

+

by Jane Doe

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ut gravida lorem. Ut turpis felis, pulvinar a semper sed, adipiscing id dolor. Pellentesque auctor nisi id magna consequat sagittis. Curabitur dapibus enim sit amet elit pharetra tincidunt feugiat nisl imperdiet. Ut convallis libero in urna ultrices accumsan. Donec sed odio eros. Donec viverra mi quis quam pulvinar at malesuada arcu rhoncus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetu

+ + diff --git a/toolkit/components/reader/tests/browser/readerModeArticleTextPlain.txt b/toolkit/components/reader/tests/browser/readerModeArticleTextPlain.txt new file mode 100644 index 0000000000..c5b7861b73 --- /dev/null +++ b/toolkit/components/reader/tests/browser/readerModeArticleTextPlain.txt @@ -0,0 +1,10 @@ + +Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Tortor id aliquet lectus proin nibh nisl condimentum. Eget magna fermentum iaculis eu non diam phasellus. Sed viverra tellus in hac habitasse platea dictumst. Quis commodo odio aenean sed. Diam vulputate ut pharetra sit amet aliquam id diam. Felis imperdiet proin fermentum leo vel orci. Diam vel quam elementum pulvinar. Vestibulum lectus mauris ultrices eros in cursus turpis massa. Sagittis vitae et leo duis ut diam. Quam elementum pulvinar etiam non quam lacus suspendisse faucibus interdum. At augue eget arcu dictum varius duis at consectetur. Bibendum enim facilisis gravida neque convallis a cras semper auctor. Suspendisse interdum consectetur libero id faucibus. Neque ornare aenean euismod elementum nisi. + +Lacus sed turpis tincidunt id aliquet. Euismod nisi porta lorem mollis. Sollicitudin aliquam ultrices sagittis orci. A diam sollicitudin tempor id eu nisl nunc. Molestie a iaculis at erat pellentesque adipiscing commodo elit. Tellus mauris a diam maecenas. Dolor morbi non arcu risus quis. Dictum non consectetur a erat nam at lectus. Convallis posuere morbi leo urna molestie. Blandit turpis cursus in hac habitasse platea dictumst quisque sagittis. Sed ullamcorper morbi tincidunt ornare massa eget egestas. Sit amet risus nullam eget felis eget nunc. Turpis in eu mi bibendum neque egestas congue. Accumsan in nisl nisi scelerisque eu ultrices vitae. Vel quam elementum pulvinar etiam non quam lacus. + +Erat velit scelerisque in dictum non consectetur a. Vulputate sapien nec sagittis aliquam malesuada bibendum. Odio facilisis mauris sit amet massa vitae tortor condimentum lacinia. Tempor nec feugiat nisl pretium. At urna condimentum mattis pellentesque id nibh tortor. Viverra tellus in hac habitasse platea dictumst. Turpis massa tincidunt dui ut ornare. Nunc id cursus metus aliquam eleifend mi. Etiam dignissim diam quis enim lobortis scelerisque fermentum. Aenean sed adipiscing diam donec adipiscing tristique risus nec feugiat. Vitae aliquet nec ullamcorper sit amet risus nullam eget felis. Quis hendrerit dolor magna eget est lorem ipsum dolor. Ultrices vitae auctor eu augue ut lectus. Curabitur gravida arcu ac tortor dignissim convallis. Justo laoreet sit amet cursus sit. Lorem ipsum dolor sit amet. Sed sed risus pretium quam vulputate dignissim suspendisse in. + +Egestas erat imperdiet sed euismod nisi porta lorem mollis. Pharetra magna ac placerat vestibulum lectus mauris ultrices eros in. Est ante in nibh mauris cursus mattis. Habitasse platea dictumst vestibulum rhoncus est pellentesque elit ullamcorper dignissim. Nunc aliquet bibendum enim facilisis gravida neque. Massa sapien faucibus et molestie. Sapien eget mi proin sed libero enim sed faucibus. Mauris a diam maecenas sed enim ut sem. Consectetur adipiscing elit duis tristique sollicitudin nibh sit. Sed arcu non odio euismod lacinia at. + +Ultricies mi quis hendrerit dolor. A erat nam at lectus urna duis convallis convallis tellus. Est sit amet facilisis magna etiam tempor orci. Porttitor massa id neque aliquam vestibulum. Lobortis feugiat vivamus at augue eget arcu dictum varius duis. Diam sit amet nisl suscipit adipiscing. Leo in vitae turpis massa. Netus et malesuada fames ac. Ac turpis egestas sed tempus urna et pharetra. Ut eu sem integer vitae justo. At erat pellentesque adipiscing commodo elit at. Consectetur purus ut faucibus pulvinar elementum integer enim. Cursus eget nunc scelerisque viverra mauris in aliquam sem. Aenean et tortor at risus viverra adipiscing at in. Platea dictumst vestibulum rhoncus est pellentesque elit ullamcorper dignissim cras. Tincidunt id aliquet risus feugiat in ante. Amet consectetur adipiscing elit pellentesque. Dignissim enim sit amet venenatis urna cursus eget nunc. Sit amet porttitor eget dolor morbi non. diff --git a/toolkit/components/reader/tests/browser/readerModeNonArticle.html b/toolkit/components/reader/tests/browser/readerModeNonArticle.html new file mode 100644 index 0000000000..e216af3c1f --- /dev/null +++ b/toolkit/components/reader/tests/browser/readerModeNonArticle.html @@ -0,0 +1,9 @@ + + + +Non article title + + + + + diff --git a/toolkit/components/reader/tests/browser/readerModeRandom.sjs b/toolkit/components/reader/tests/browser/readerModeRandom.sjs new file mode 100644 index 0000000000..f6bb15c06a --- /dev/null +++ b/toolkit/components/reader/tests/browser/readerModeRandom.sjs @@ -0,0 +1,23 @@ +// Generate a article ending in a piece of text with some random values in it. + +let readerModeText = ` + + +Article title + + + +
Site header
+
+

Article title

+

by Jane Doe

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ut gravida lorem. Ut turpis felis, pulvinar a semper sed, adipiscing id dolor. Pellentesque auctor nisi id magna consequat sagittis. Curabitur dapibus enim sit amet elit pharetra tincidunt feugiat nisl imperdiet. Ut convallis libero in urna ultrices accumsan. Donec sed odio eros. Donec viverra mi quis quam pulvinar at malesuada arcu rhoncus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetu

+`; + +function handleRequest(aRequest, aResponse) { + aResponse.setStatusLine(aRequest.httpVersion, 200); + aResponse.setHeader("Content-Type", "text/html", false); + aResponse.write( + readerModeText + "

" + Date.now() + "," + Math.random() + "

" + ); +} diff --git a/toolkit/components/reader/tests/browser/setSameSiteCookie.html b/toolkit/components/reader/tests/browser/setSameSiteCookie.html new file mode 100644 index 0000000000..67bb714922 --- /dev/null +++ b/toolkit/components/reader/tests/browser/setSameSiteCookie.html @@ -0,0 +1,9 @@ + + + + + + +

This page just set a cookie with the SameSite attribute.

+ + diff --git a/toolkit/components/reader/tests/browser/setSameSiteCookie.html^headers^ b/toolkit/components/reader/tests/browser/setSameSiteCookie.html^headers^ new file mode 100644 index 0000000000..c0229c93b6 --- /dev/null +++ b/toolkit/components/reader/tests/browser/setSameSiteCookie.html^headers^ @@ -0,0 +1 @@ +Set-Cookie: foo=bar; Path='/' ; SameSite=strict diff --git a/toolkit/components/reader/tests/chrome/chrome.toml b/toolkit/components/reader/tests/chrome/chrome.toml new file mode 100644 index 0000000000..e416c49181 --- /dev/null +++ b/toolkit/components/reader/tests/chrome/chrome.toml @@ -0,0 +1,3 @@ +[DEFAULT] + +["test_color_input.html"] diff --git a/toolkit/components/reader/tests/chrome/test_color_input.html b/toolkit/components/reader/tests/chrome/test_color_input.html new file mode 100644 index 0000000000..4cd8cde77b --- /dev/null +++ b/toolkit/components/reader/tests/chrome/test_color_input.html @@ -0,0 +1,39 @@ + + + + + ColorInput Tests + + + + + +

+
+ +
+
+  
+
+ + -- cgit v1.2.3