diff options
Diffstat (limited to '')
9 files changed, 430 insertions, 0 deletions
diff --git a/browser/base/content/test/pageStyle/browser.toml b/browser/base/content/test/pageStyle/browser.toml new file mode 100644 index 0000000000..27ab96fcc2 --- /dev/null +++ b/browser/base/content/test/pageStyle/browser.toml @@ -0,0 +1,15 @@ +[DEFAULT] +support-files = [ + "head.js", + "page_style_sample.html", + "style.css", +] + +["browser_disable_author_style_oop.js"] +https_first_disabled = true +support-files = ["page_style.html"] + +["browser_page_style_menu.js"] +support-files = ["page_style_only_alternates.html"] + +["browser_page_style_menu_update.js"] diff --git a/browser/base/content/test/pageStyle/browser_disable_author_style_oop.js b/browser/base/content/test/pageStyle/browser_disable_author_style_oop.js new file mode 100644 index 0000000000..8ae829817d --- /dev/null +++ b/browser/base/content/test/pageStyle/browser_disable_author_style_oop.js @@ -0,0 +1,100 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +async function getColor(aSpawnTarget) { + return SpecialPowers.spawn(aSpawnTarget, [], function () { + return content.document.defaultView.getComputedStyle( + content.document.querySelector("p") + ).color; + }); +} + +async function insertIFrame() { + let bc = gBrowser.selectedBrowser.browsingContext; + let len = bc.children.length; + + const kURL = + WEB_ROOT.replace("example.com", "example.net") + "page_style.html"; + await SpecialPowers.spawn(gBrowser.selectedBrowser, [kURL], function (url) { + return new Promise(function (resolve) { + let e = content.document.createElement("iframe"); + e.src = url; + e.onload = () => resolve(); + content.document.body.append(e); + }); + }); + + // Wait for the new frame to get a pres shell and be styled. + await BrowserTestUtils.waitForCondition(async function () { + return ( + bc.children.length == len + 1 && (await getColor(bc.children[len])) != "" + ); + }); +} + +// Test that inserting an iframe with a URL that is loaded OOP with Fission +// enabled correctly matches the tab's author style disabled state. +add_task(async function test_disable_style() { + let tab = await BrowserTestUtils.openNewForegroundTab( + gBrowser, + WEB_ROOT + "page_style.html", + /* waitForLoad = */ true + ); + + let bc = gBrowser.selectedBrowser.browsingContext; + + await insertIFrame(); + + is( + await getColor(bc), + "rgb(0, 0, 255)", + "parent color before disabling style" + ); + is( + await getColor(bc.children[0]), + "rgb(0, 0, 255)", + "first child color before disabling style" + ); + + gPageStyleMenu.disableStyle(); + + is(await getColor(bc), "rgb(0, 0, 0)", "parent color after disabling style"); + is( + await getColor(bc.children[0]), + "rgb(0, 0, 0)", + "first child color after disabling style" + ); + + await insertIFrame(); + + is( + await getColor(bc.children[1]), + "rgb(0, 0, 0)", + "second child color after disabling style" + ); + + await BrowserTestUtils.reloadTab(tab, true); + + // Check the menu: + let { menupopup } = document.getElementById("pageStyleMenu"); + gPageStyleMenu.fillPopup(menupopup); + Assert.equal( + menupopup.querySelector("menuitem[checked='true']").dataset.l10nId, + "menu-view-page-style-no-style", + "No style menu should be checked." + ); + + // check the page content still has a disabled author style: + Assert.ok( + await SpecialPowers.spawn( + tab.linkedBrowser, + [], + () => content.docShell.docViewer.authorStyleDisabled + ), + "Author style should still be disabled." + ); + + BrowserTestUtils.removeTab(tab); +}); diff --git a/browser/base/content/test/pageStyle/browser_page_style_menu.js b/browser/base/content/test/pageStyle/browser_page_style_menu.js new file mode 100644 index 0000000000..ac543f48f5 --- /dev/null +++ b/browser/base/content/test/pageStyle/browser_page_style_menu.js @@ -0,0 +1,177 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +function fillPopupAndGetItems() { + let menupopup = document.getElementById("pageStyleMenu").menupopup; + gPageStyleMenu.fillPopup(menupopup); + return Array.from(menupopup.querySelectorAll("menuseparator ~ menuitem")); +} + +function getRootColor() { + return SpecialPowers.spawn(gBrowser.selectedBrowser, [], function () { + return content.document.defaultView.getComputedStyle( + content.document.documentElement + ).color; + }); +} + +const RED = "rgb(255, 0, 0)"; +const LIME = "rgb(0, 255, 0)"; +const BLUE = "rgb(0, 0, 255)"; + +const kStyleSheetsInPageStyleSample = 18; + +/* + * Test that the right stylesheets do (and others don't) show up + * in the page style menu. + */ +add_task(async function test_menu() { + let tab = await BrowserTestUtils.openNewForegroundTab( + gBrowser, + "about:blank", + false + ); + let browser = tab.linkedBrowser; + BrowserTestUtils.startLoadingURIString( + browser, + WEB_ROOT + "page_style_sample.html" + ); + await promiseStylesheetsLoaded(browser, kStyleSheetsInPageStyleSample); + + let menuitems = fillPopupAndGetItems(); + let items = menuitems.map(el => ({ + label: el.getAttribute("label"), + checked: el.getAttribute("checked") == "true", + })); + + let validLinks = await SpecialPowers.spawn( + gBrowser.selectedBrowser, + [items], + function (contentItems) { + let contentValidLinks = 0; + for (let el of content.document.querySelectorAll("link, style")) { + var title = el.getAttribute("title"); + var rel = el.getAttribute("rel"); + var media = el.getAttribute("media"); + var idstring = + el.nodeName + + " " + + (title ? title : "without title and") + + ' with rel="' + + rel + + '"' + + (media ? ' and media="' + media + '"' : ""); + + var item = contentItems.filter(aItem => aItem.label == title); + var found = item.length == 1; + var checked = found && item[0].checked; + + switch (el.getAttribute("data-state")) { + case "0": + ok(!found, idstring + " should not show up in page style menu"); + break; + case "1": + contentValidLinks++; + ok(found, idstring + " should show up in page style menu"); + ok(!checked, idstring + " should not be selected"); + break; + case "2": + contentValidLinks++; + ok(found, idstring + " should show up in page style menu"); + ok(checked, idstring + " should be selected"); + break; + default: + throw new Error( + "data-state attribute is missing or has invalid value" + ); + } + } + return contentValidLinks; + } + ); + + ok(menuitems.length, "At least one item in the menu"); + is(menuitems.length, validLinks, "all valid links found"); + + is(await getRootColor(), LIME, "Root should be lime (styles should apply)"); + + let disableStyles = document.getElementById("menu_pageStyleNoStyle"); + let defaultStyles = document.getElementById("menu_pageStylePersistentOnly"); + let otherStyles = menuitems[0].parentNode.querySelector("[label='28']"); + + // Assert that the menu works as expected. + disableStyles.click(); + + await TestUtils.waitForCondition(async function () { + let color = await getRootColor(); + return color != LIME && color != BLUE; + }, "ensuring disabled styles work"); + + otherStyles.click(); + + await TestUtils.waitForCondition(async function () { + let color = await getRootColor(); + return color == BLUE; + }, "ensuring alternate styles work. clicking on: " + otherStyles.label); + + defaultStyles.click(); + + info("ensuring default styles work"); + await TestUtils.waitForCondition(async function () { + let color = await getRootColor(); + return color == LIME; + }, "ensuring default styles work"); + + BrowserTestUtils.removeTab(tab); +}); + +add_task(async function test_default_style_with_no_sheets() { + const PAGE = WEB_ROOT + "page_style_only_alternates.html"; + await BrowserTestUtils.withNewTab( + { + gBrowser, + url: PAGE, + waitForLoad: true, + }, + async function (browser) { + await promiseStylesheetsLoaded(browser, 2); + + let menuitems = fillPopupAndGetItems(); + is(menuitems.length, 2, "Should've found two style sets"); + is( + await getRootColor(), + BLUE, + "First found style should become the preferred one and apply" + ); + + // Reset the styles. + document.getElementById("menu_pageStylePersistentOnly").click(); + await TestUtils.waitForCondition(async function () { + let color = await getRootColor(); + return color != BLUE && color != RED; + }); + + ok( + true, + "Should reset the style properly even if there are no non-alternate stylesheets" + ); + } + ); +}); + +add_task(async function test_page_style_file() { + const FILE_PAGE = Services.io.newFileURI( + new FileUtils.File(getTestFilePath("page_style_sample.html")) + ).spec; + await BrowserTestUtils.withNewTab(FILE_PAGE, async function (browser) { + await promiseStylesheetsLoaded(browser, kStyleSheetsInPageStyleSample); + let menuitems = fillPopupAndGetItems(); + is( + menuitems.length, + kStyleSheetsInPageStyleSample, + "Should have the right amount of items even for file: URI." + ); + }); +}); diff --git a/browser/base/content/test/pageStyle/browser_page_style_menu_update.js b/browser/base/content/test/pageStyle/browser_page_style_menu_update.js new file mode 100644 index 0000000000..e406bdcc0b --- /dev/null +++ b/browser/base/content/test/pageStyle/browser_page_style_menu_update.js @@ -0,0 +1,49 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const PAGE = WEB_ROOT + "page_style_sample.html"; + +/** + * Tests that the Page Style menu shows the currently + * selected Page Style after a new one has been selected. + */ +add_task(async function () { + let tab = await BrowserTestUtils.openNewForegroundTab( + gBrowser, + "about:blank", + false + ); + let browser = tab.linkedBrowser; + BrowserTestUtils.startLoadingURIString(browser, PAGE); + await promiseStylesheetsLoaded(browser, 18); + + let menupopup = document.getElementById("pageStyleMenu").menupopup; + gPageStyleMenu.fillPopup(menupopup); + + // page_style_sample.html should default us to selecting the stylesheet + // with the title "6" first. + let selected = menupopup.querySelector("menuitem[checked='true']"); + is( + selected.getAttribute("label"), + "6", + "Should have '6' stylesheet selected by default" + ); + + // Now select stylesheet "1" + let target = menupopup.querySelector("menuitem[label='1']"); + target.doCommand(); + + gPageStyleMenu.fillPopup(menupopup); + // gPageStyleMenu empties out the menu between opens, so we need + // to get a new reference to the selected menuitem + selected = menupopup.querySelector("menuitem[checked='true']"); + is( + selected.getAttribute("label"), + "1", + "Should now have stylesheet 1 selected" + ); + + BrowserTestUtils.removeTab(tab); +}); diff --git a/browser/base/content/test/pageStyle/head.js b/browser/base/content/test/pageStyle/head.js new file mode 100644 index 0000000000..57d5947d50 --- /dev/null +++ b/browser/base/content/test/pageStyle/head.js @@ -0,0 +1,30 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +const WEB_ROOT = getRootDirectory(gTestPath).replace( + "chrome://mochitests/content", + "https://example.com" +); + +/** + * Waits for the stylesheets to be loaded into the browser menu. + * + * @param browser + * The browser that contains the webpage we're testing. + * @param styleSheetCount + * How many stylesheets we expect to be loaded. + * @return Promise + */ +function promiseStylesheetsLoaded(browser, styleSheetCount) { + return TestUtils.waitForCondition(() => { + let actor = + browser.browsingContext?.currentWindowGlobal?.getActor("PageStyle"); + if (!actor) { + info("No jswindowactor (yet?)"); + return false; + } + let sheetCount = actor.getSheetInfo().filteredStyleSheets.length; + info(`waiting for sheets: ${sheetCount}`); + return sheetCount >= styleSheetCount; + }, "waiting for style sheets to load"); +} diff --git a/browser/base/content/test/pageStyle/page_style.html b/browser/base/content/test/pageStyle/page_style.html new file mode 100644 index 0000000000..c16a9ea4aa --- /dev/null +++ b/browser/base/content/test/pageStyle/page_style.html @@ -0,0 +1,8 @@ +<!DOCTYPE html> +<style> +p { color: blue; font-weight: bold; } +</style> +<p>Some text.</p> +<script> +let gFramesLoaded = 0; +</script> diff --git a/browser/base/content/test/pageStyle/page_style_only_alternates.html b/browser/base/content/test/pageStyle/page_style_only_alternates.html new file mode 100644 index 0000000000..b5f4a8181c --- /dev/null +++ b/browser/base/content/test/pageStyle/page_style_only_alternates.html @@ -0,0 +1,5 @@ +<!doctype html> +<title>Test for the page style menu</title> +<!-- We only have alternates here intentionally. "Basic Page Style" should still work and remove the blue / red colors --> +<style title="blue">:root { color: blue }</style> +<style title="red">:root { color: red}</style> diff --git a/browser/base/content/test/pageStyle/page_style_sample.html b/browser/base/content/test/pageStyle/page_style_sample.html new file mode 100644 index 0000000000..ec89e99bc9 --- /dev/null +++ b/browser/base/content/test/pageStyle/page_style_sample.html @@ -0,0 +1,45 @@ +<html> + <head> + <title>Test for page style menu</title> + <!-- data-state values: + 0: should not appear in the page style menu + 1: should appear in the page style menu + 2: should appear in the page style menu as the selected stylesheet --> + <style data-state="0"> + /* Some default styles to ensure that disabling styles works */ + :root { color: lime } + </style> + <link data-state="1" href="style.css" title="1" rel="alternate stylesheet"> + <link data-state="0" title="2" rel="alternate stylesheet"> + <link data-state="0" href="style.css" rel="alternate stylesheet"> + <link data-state="0" href="style.css" title="" rel="alternate stylesheet"> + <link data-state="1" href="style.css" title="3" rel="stylesheet alternate"> + <link data-state="1" href="style.css" title="4" rel=" alternate stylesheet "> + <link data-state="1" href="style.css" title="5" rel="alternate stylesheet"> + <link data-state="2" href="style.css" title="6" rel="stylesheet"> + <link data-state="1" href="style.css" title="7" rel="foo stylesheet"> + <link data-state="0" href="style.css" title="8" rel="alternate"> + <link data-state="1" href="style.css" title="9" rel="alternate STYLEsheet"> + <link data-state="1" href="style.css" title="10" rel="alternate stylesheet" media=""> + <link data-state="1" href="style.css" title="11" rel="alternate stylesheet" media="all"> + <link data-state="1" href="style.css" title="12" rel="alternate stylesheet" media="ALL "> + <link data-state="1" href="style.css" title="13" rel="alternate stylesheet" media="screen"> + <link data-state="1" href="style.css" title="14" rel="alternate stylesheet" media=" Screen"> + <link data-state="0" href="style.css" title="15" rel="alternate stylesheet" media="screen foo"> + <link data-state="0" href="style.css" title="16" rel="alternate stylesheet" media="all screen"> + <link data-state="0" href="style.css" title="17" rel="alternate stylesheet" media="foo bar"> + <link data-state="1" href="style.css" title="18" rel="alternate stylesheet" media="all,screen"> + <link data-state="1" href="style.css" title="19" rel="alternate stylesheet" media="all, screen"> + <link data-state="0" href="style.css" title="20" rel="alternate stylesheet" media="all screen"> + <link data-state="0" href="style.css" title="21" rel="alternate stylesheet" media="foo"> + <link data-state="0" href="style.css" title="22" rel="alternate stylesheet" media="allscreen"> + <link data-state="0" href="style.css" title="23" rel="alternate stylesheet" media="_all"> + <link data-state="0" href="style.css" title="24" rel="alternate stylesheet" media="not screen"> + <link data-state="1" href="style.css" title="25" rel="alternate stylesheet" media="only screen"> + <link data-state="1" href="style.css" title="26" rel="alternate stylesheet" media="screen and (min-device-width: 1px)"> + <link data-state="0" href="style.css" title="27" rel="alternate stylesheet" media="screen and (max-device-width: 1px)"> + <style data-state="1" title="28">:root { color: blue }</style> + <link data-state="1" href="style.css" title="29" rel="alternate stylesheet" disabled> + </head> + <body></body> +</html> diff --git a/browser/base/content/test/pageStyle/style.css b/browser/base/content/test/pageStyle/style.css new file mode 100644 index 0000000000..c8337cea19 --- /dev/null +++ b/browser/base/content/test/pageStyle/style.css @@ -0,0 +1 @@ +.unused { /* This sheet is here for testing purposes. */ } |