diff options
Diffstat (limited to 'dom/tests/mochitest/general/test_contentViewer_overrideDPPX.html')
-rw-r--r-- | dom/tests/mochitest/general/test_contentViewer_overrideDPPX.html | 428 |
1 files changed, 428 insertions, 0 deletions
diff --git a/dom/tests/mochitest/general/test_contentViewer_overrideDPPX.html b/dom/tests/mochitest/general/test_contentViewer_overrideDPPX.html new file mode 100644 index 0000000000..a5d15d0cad --- /dev/null +++ b/dom/tests/mochitest/general/test_contentViewer_overrideDPPX.html @@ -0,0 +1,428 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>nsIDocumentViewer::overrideDPPX test</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/EventUtils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"> +</head> + +<body> + +<iframe></iframe> +<img> + +<script type="application/javascript"> + +SimpleTest.waitForExplicitFinish(); + +const frameWindow = document.querySelector("iframe").contentWindow; +const image = document.querySelector("img"); + +const originalDPR = window.devicePixelRatio; +const originalZoom = SpecialPowers.getFullZoom(window); +const dppx = originalDPR * 1.5; +const zoom = originalZoom * 0.5; + +const imageSets = { + "1x" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA" + + "GUlEQVQ4jWP4z8DwnxLMMGrAqAGjBgwXAwAwxP4QWURl4wAAAABJRU5ErkJggg==", + "1.5x": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA" + + "GElEQVQ4jWNgaGD4TxEeNWDUgFEDhosBAOsIfxAZ/CYXAAAAAElFTkSuQmCC", + "2x" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA" + + "GElEQVQ4jWNgYPj/nzI8asCoAaMGDBMDADKm/hBZaHKGAAAAAElFTkSuQmCC", + "8x" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA" + + "GklEQVQ4jWP4f+D0f0oww6gBowaMGjBcDAAAskKJLhIvZvgAAAAASUVORK5CYII=", +}; + +const setOverrideDPPX = (value) => { + if (value > 0) { + info(`override window's dppx to ${value}`); + } else { + info(`restore window's dppx to default value`); + } + + return SpecialPowers.spawnChrome([value], dppx => { + browsingContext.top.overrideDPPX = dppx; + }); +}; + +const setFullZoom = (value) => { + info(`set window's fullZoom to ${value}`); + SpecialPowers.setFullZoom(window, value); +} + +const createFontStyleForDPPX = (doc, value, size) => { + info(`adding a stylesheet that set font size to ${size}px for ${value}dppx`); + + let style = doc.createElement("style"); + + style.setAttribute("media", `(resolution: ${value}dppx)`); + + doc.head.appendChild(style); + + style.sheet.insertRule(`body {font-size: ${size}px}`, 0); + + return style; +} + +const getBodyFontSize = (w) => w.getComputedStyle(w.document.body).fontSize; + +const assertValuesAreInitial = () => { + is(window.devicePixelRatio, originalDPR, + "devicePixelRatio has the original value."); + is(SpecialPowers.getFullZoom(window), originalZoom, + "fullZoom has the original value."); + + is(frameWindow.devicePixelRatio, originalDPR, + "devicePixelRatio has the original value."); + is(SpecialPowers.getFullZoom(frameWindow), originalZoom, + "fullZoom has the original value."); +} + +const waitForMediaQueryListEvent = (mediaQueryList) => { + return new Promise(resolve => { + mediaQueryList.addListener(function listener() { + ok(true, "MediaQueryList's listener invoked for " + mediaQueryList.media); + mediaQueryList.removeListener(listener); + // We need to evacuate a media query list event to avoid changing any + // media features inside this callback (and microtasks for the callbacks), + // because we currently dispatch media query list events during flush + // pending styles, and we want to make sure there is no pending media + // feature changes after the event handling. + // This workaround should be dropped in bug 1437688. + setTimeout(resolve, 0); + }); + }); +} + +const gTests = { + "test overrideDPPX with devicePixelRatio": async (done) => { + assertValuesAreInitial(); + + await setOverrideDPPX(dppx); + + is(window.devicePixelRatio, dppx, + "devicePixelRatio overridden."); + is(frameWindow.devicePixelRatio, dppx, + "frame's devicePixelRatio overridden."); + + await setOverrideDPPX(0); + + is(window.devicePixelRatio, originalDPR, + "devicePixelRatio back to default."); + is(frameWindow.devicePixelRatio, originalDPR, + "frame's devicePixelRatio back to default."); + + done(); + }, + "test overrideDPPX with devicePixelRatio and fullZoom": async (done) => { + assertValuesAreInitial(); + + setFullZoom(zoom); + await setOverrideDPPX(dppx); + + is(window.devicePixelRatio, dppx, + "devicePixelRatio overridden; fullZoom ignored"); + is(SpecialPowers.wrap(window).devicePixelRatio, originalDPR * zoom, + "devicePixelRatio is right for privileged code"); + is(frameWindow.devicePixelRatio, dppx, + "frame's devicePixelRatio overridden; fullZoom ignored"); + is(SpecialPowers.wrap(frameWindow).devicePixelRatio, originalDPR * zoom, + "frame's devicePixelRatio is right for privileged code"); + + await setOverrideDPPX(0); + + is(window.devicePixelRatio, originalDPR * zoom, + "devicePixelRatio now is affected by fullZoom"); + is(frameWindow.devicePixelRatio, originalDPR * zoom, + "frame's devicePixelRatio now is affected by fullZoom"); + isnot(dppx, originalDPR * zoom, + "test is no longer testing what it should be"); + + setFullZoom(originalZoom); + + is(window.devicePixelRatio, originalDPR, + "devicePixelRatio back to default."); + is(frameWindow.devicePixelRatio, originalDPR, + "frame's devicePixelRatio back to default."); + + done(); + + }, + "test overrideDPPX with media queries": async (done) => { + assertValuesAreInitial(); + + let frameDoc = frameWindow.document; + + let originalFontSize = getBodyFontSize(window); + let frameOriginalFontSize = getBodyFontSize(frameWindow); + + let style = createFontStyleForDPPX(document, dppx, "32"); + let frameStyle = createFontStyleForDPPX(frameDoc, dppx, "32"); + + let currentFontSize = getBodyFontSize(window); + let frameCurrentFontSize = getBodyFontSize(frameWindow); + + is(currentFontSize, originalFontSize, + "media queries are not applied yet"); + is(frameCurrentFontSize, frameOriginalFontSize, + "frame's media queries are not applied yet"); + + await setOverrideDPPX(dppx); + + currentFontSize = getBodyFontSize(window); + frameCurrentFontSize = getBodyFontSize(frameWindow); + + isnot(currentFontSize, originalFontSize, + "media queries are applied."); + isnot(frameCurrentFontSize, frameOriginalFontSize, + "frame's media queries are applied."); + + is(currentFontSize, "32px", + "font size has the expected value."); + is(frameCurrentFontSize, "32px", + "frame's font size has the expected value."); + + await setOverrideDPPX(0); + + currentFontSize = getBodyFontSize(window); + frameCurrentFontSize = getBodyFontSize(frameWindow); + + is(currentFontSize, originalFontSize, + "media queries are not applied anymore."); + is(frameCurrentFontSize, frameOriginalFontSize, + "media queries are not applied anymore."); + + style.remove(); + frameStyle.remove(); + + done(); + }, + "test overrideDPPX with media queries and fullZoom": async (done) => { + assertValuesAreInitial(); + + let frameDoc = frameWindow.document; + + let styles = [ + createFontStyleForDPPX(document, originalDPR, "23"), + createFontStyleForDPPX(document, dppx, "32"), + createFontStyleForDPPX(document, originalDPR * zoom, "48"), + createFontStyleForDPPX(frameDoc, originalDPR, "23"), + createFontStyleForDPPX(frameDoc, dppx, "32"), + createFontStyleForDPPX(frameDoc, originalDPR * zoom, "48") + ]; + + let currentFontSize = getBodyFontSize(window); + let frameCurrentFontSize = getBodyFontSize(frameWindow); + is(currentFontSize, "23px", + "media queries are not applied yet"); + is(frameCurrentFontSize, "23px", + "frame's media queries are not applied yet"); + + setFullZoom(zoom); + await setOverrideDPPX(dppx); + + currentFontSize = getBodyFontSize(window); + frameCurrentFontSize = getBodyFontSize(frameWindow); + is(currentFontSize, "32px", + "media queries are applied for overridden DDPX; fullZoom ignored."); + is(frameCurrentFontSize, "32px", + "frame's media queries are applied for overridden DDPX; fullZoom ignored."); + + await setOverrideDPPX(0); + + currentFontSize = getBodyFontSize(window); + frameCurrentFontSize = getBodyFontSize(frameWindow); + is(currentFontSize, "48px", + "media queries are applied for fullZoom."); + is(frameCurrentFontSize, "48px", + "frame's media queries are applied for fullZoom."); + + setFullZoom(originalZoom); + + currentFontSize = getBodyFontSize(window); + frameCurrentFontSize = getBodyFontSize(frameWindow); + is(currentFontSize, "23px", + "media queries are not applied anymore."); + is(frameCurrentFontSize, "23px", + "frame's media queries are not applied anymore."); + + styles.forEach(style => style.remove()); + + done(); + }, + "test OverrideDPPX with MediaQueryList": (done) => { + assertValuesAreInitial(); + + let promises = [ + waitForMediaQueryListEvent( + window.matchMedia(`(resolution: ${dppx}dppx)`)), + waitForMediaQueryListEvent( + frameWindow.matchMedia(`(resolution: ${dppx}dppx)`)), + ]; + + Promise.all(promises) + .then(() => setOverrideDPPX(0)) + .then(done, e => {throw e}); + + setOverrideDPPX(dppx); + }, + "test OverrideDPPX with MediaQueryList and fullZoom": async (done) => { + assertValuesAreInitial(); + + let promises = [ + waitForMediaQueryListEvent( + window.matchMedia(`(resolution: ${dppx}dppx)`)), + waitForMediaQueryListEvent( + window.matchMedia(`(resolution: ${originalDPR * zoom}dppx)`)), + ]; + + await setOverrideDPPX(dppx); + setFullZoom(zoom); + + promises[0] + .then(() => setOverrideDPPX(0)) + .then(promises[1]) + .then(() => setFullZoom(originalZoom)) + .then(done, e => {throw e}); + }, + "test OverrideDPPX is kept on document navigation": async (done) => { + assertValuesAreInitial(); + + let frameOriginalFontSize = getBodyFontSize(frameWindow); + let frameStyle = createFontStyleForDPPX(frameWindow.document, dppx, "32"); + let frameCurrentFontSize = getBodyFontSize(frameWindow); + + is(frameCurrentFontSize, frameOriginalFontSize, + "frame's media queries are not applied yet"); + + await setOverrideDPPX(dppx); + + frameCurrentFontSize = getBodyFontSize(frameWindow); + + is(frameWindow.devicePixelRatio, dppx, + "frame's devicePixelRatio overridden."); + isnot(frameCurrentFontSize, frameOriginalFontSize, + "frame's media queries are applied."); + is(frameCurrentFontSize, "32px", + "frame's font size has the expected value."); + + frameWindow.frameElement.addEventListener("load", async function() { + frameStyle = createFontStyleForDPPX(frameWindow.document, dppx, "32"); + + frameCurrentFontSize = getBodyFontSize(frameWindow); + + is(frameWindow.devicePixelRatio, dppx, + "frame's devicePixelRatio is still overridden."); + isnot(frameCurrentFontSize, frameOriginalFontSize, + "frame's media queries are still applied."); + is(frameCurrentFontSize, "32px", + "frame's font size has still the expected value."); + + frameStyle.remove(); + + await setOverrideDPPX(0); + + done(); + }, {once: true}); + + frameWindow.location.reload(true); + }, + + "test overrideDPPX with srcset": async function (done) { + assertValuesAreInitial(); + + let loaded; + + // Set the image srcset and default src. This is delayed until this test so + // that dppx overrides in other test blocks don't trigger load event on the + // image. + loaded = new Promise(resolve => image.onload = resolve); + image.srcset = Object.entries(imageSets).map(v => v[1] + " " + v[0]).join(", "); + image.src = imageSets["1x"]; + await loaded; + + let originalSrc = image.currentSrc; + + // Make sure to test some very large value that can't be the default density + // so that the first override will always trigger a load. + isnot(originalDPR, 8, "originalDPR differs from final test value"); + loaded = new Promise(resolve => image.onload = resolve); + await setOverrideDPPX(8); + await loaded; + + is(image.currentSrc, imageSets["8x"], + "Image is properly set for 8dppx."); + + loaded = new Promise(resolve => image.onload = resolve); + await setOverrideDPPX(1); + await loaded; + + is(image.currentSrc, imageSets["1x"], + "Image url is properly set for 1dppx."); + + loaded = new Promise(resolve => image.onload = resolve); + await setOverrideDPPX(1.5); + await loaded; + + is(image.currentSrc, imageSets["1.5x"], + "Image url is properly set for 1.5dppx."); + + loaded = new Promise(resolve => image.onload = resolve); + await setOverrideDPPX(2); + await loaded; + + is(image.currentSrc, imageSets["2x"], + "Image is properly set for 2dppx."); + + // Make sure to test some very large value that can't be the default density + // so that resetting to the default will always trigger a load. + isnot(originalDPR, 8, "originalDPR differs from final test value"); + loaded = new Promise(resolve => image.onload = resolve); + await setOverrideDPPX(8); + await loaded; + + is(image.currentSrc, imageSets["8x"], + "Image is properly set for 8dppx."); + + loaded = new Promise(resolve => image.onload = resolve); + await setOverrideDPPX(0); + await loaded; + + is(image.currentSrc, originalSrc, + "Image is properly restored to the default value."); + + // Clear sources so any future dppx test blocks don't trigger image loads. + image.srcset = ""; + image.src = ""; + + done(); + } +}; + +function* runner(tests) { + for (let name of Object.keys(tests)) { + info(name); + tests[name](next); + yield undefined; + } +}; + +const gTestRunner = runner(gTests); + +function next() { + SimpleTest.executeSoon(function() { + if (gTestRunner.next().done) { + SimpleTest.finish(); + } + }); +} + +// Run the tests +addLoadEvent(next); + +</script> + +</body> +</html> |