browser_styleeditor_media_sidebar_links.js (5148B)
1 /* Any copyright is dedicated to the Public Domain. 2 http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 "use strict"; 5 6 /** 7 * Tests responsive mode links for `@media` sidebar width and height related 8 * conditions. 9 */ 10 11 loader.lazyRequireGetter( 12 this, 13 "ResponsiveUIManager", 14 "resource://devtools/client/responsive/manager.js" 15 ); 16 17 const TESTCASE_URI = TEST_BASE_HTTPS + "media-rules.html"; 18 const responsiveModeToggleClass = ".media-responsive-mode-toggle"; 19 20 add_task(async function () { 21 // ensure that original RDM size is big enough so it doesn't match the 22 // media queries by default. 23 await pushPref("devtools.responsive.viewport.width", 1000); 24 await pushPref("devtools.responsive.viewport.height", 1000); 25 26 const { ui } = await openStyleEditorForURL(TESTCASE_URI); 27 28 const editor = ui.editors[1]; 29 await openEditor(editor); 30 31 const tab = gBrowser.selectedTab; 32 testNumberOfLinks(editor); 33 await testMediaLink(editor, tab, ui, 2, "width", 550); 34 await testMediaLink(editor, tab, ui, 3, "height", 300); 35 36 const onMediaChange = waitForManyEvents(ui, 1000); 37 await closeRDM(tab); 38 39 info("Wait for at-rules-list-changed events to settle on StyleEditorUI"); 40 await onMediaChange; 41 doFinalChecks(editor); 42 }); 43 44 function testNumberOfLinks(editor) { 45 const sidebar = editor.details.querySelector(".stylesheet-sidebar"); 46 const conditions = sidebar.querySelectorAll(".at-rule-condition"); 47 48 info("Testing if media rules have the appropriate number of links"); 49 ok( 50 !conditions[0].querySelector(responsiveModeToggleClass), 51 "There should be no links in the first media rule." 52 ); 53 ok( 54 !conditions[1].querySelector(responsiveModeToggleClass), 55 "There should be no links in the second media rule." 56 ); 57 ok( 58 conditions[2].querySelector(responsiveModeToggleClass), 59 "There should be 1 responsive mode link in the media rule" 60 ); 61 is( 62 conditions[3].querySelectorAll(responsiveModeToggleClass).length, 63 2, 64 "There should be 2 responsive mode links in the media rule" 65 ); 66 } 67 68 async function testMediaLink(editor, tab, ui, itemIndex, type, value) { 69 const sidebar = editor.details.querySelector(".stylesheet-sidebar"); 70 const conditions = sidebar.querySelectorAll(".at-rule-condition"); 71 const onRDMOpened = once(ui, "responsive-mode-opened"); 72 73 ok( 74 sidebar 75 .querySelectorAll(".at-rule-condition") 76 [itemIndex].classList.contains("media-condition-unmatched"), 77 `The ${type} condition is not matched when not in responsive mode` 78 ); 79 80 info("Launching responsive mode"); 81 conditions[itemIndex].querySelector(responsiveModeToggleClass).click(); 82 await onRDMOpened; 83 const rdmUI = ResponsiveUIManager.getResponsiveUIForTab(tab); 84 await waitForResizeTo(rdmUI, type, value); 85 rdmUI.transitionsEnabled = false; 86 87 info("Wait for RDM ui to be fully loaded"); 88 await waitForRDMLoaded(rdmUI); 89 90 // Ensure that the content has reflowed, which will ensure that all the 91 // element classes are reported correctly. 92 await promiseContentReflow(rdmUI); 93 94 ok( 95 ResponsiveUIManager.isActiveForTab(tab), 96 "Responsive mode should be active." 97 ); 98 await waitFor(() => { 99 const el = sidebar.querySelectorAll(".at-rule-condition")[itemIndex]; 100 return !el.classList.contains("media-condition-unmatched"); 101 }); 102 ok(true, "media rule should now be matched after responsive mode is active"); 103 104 const dimension = (await getSizing(rdmUI))[type]; 105 is(dimension, value, `${type} should be properly set.`); 106 } 107 108 function doFinalChecks(editor) { 109 const sidebar = editor.details.querySelector(".stylesheet-sidebar"); 110 let conditions = sidebar.querySelectorAll(".at-rule-condition"); 111 conditions = sidebar.querySelectorAll(".at-rule-condition"); 112 ok( 113 conditions[2].classList.contains("media-condition-unmatched"), 114 "The width condition should now be unmatched" 115 ); 116 ok( 117 conditions[3].classList.contains("media-condition-unmatched"), 118 "The height condition should now be unmatched" 119 ); 120 } 121 122 /* Helpers */ 123 function waitForResizeTo(rdmUI, type, value) { 124 return new Promise(resolve => { 125 const onResize = data => { 126 if (data[type] != value) { 127 return; 128 } 129 rdmUI.off("content-resize", onResize); 130 info(`Got content-resize to a ${type} of ${value}`); 131 resolve(); 132 }; 133 info(`Waiting for content-resize to a ${type} of ${value}`); 134 rdmUI.on("content-resize", onResize); 135 }); 136 } 137 138 function promiseContentReflow(ui) { 139 return SpecialPowers.spawn(ui.getViewportBrowser(), [], async function () { 140 return new Promise(resolve => { 141 content.window.requestAnimationFrame(() => { 142 content.window.requestAnimationFrame(resolve); 143 }); 144 }); 145 }); 146 } 147 148 async function getSizing(rdmUI) { 149 const browser = rdmUI.getViewportBrowser(); 150 const sizing = await SpecialPowers.spawn(browser, [], async function () { 151 return { 152 width: content.innerWidth, 153 height: content.innerHeight, 154 }; 155 }); 156 return sizing; 157 } 158 159 function openEditor(editor) { 160 getLinkFor(editor).click(); 161 162 return editor.getSourceEditor(); 163 } 164 165 function getLinkFor(editor) { 166 return editor.summary.querySelector(".stylesheet-name"); 167 }