browser_css_autocompletion.js (5238B)
1 /* Any copyright is dedicated to the Public Domain. 2 http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 "use strict"; 5 6 const CSSCompleter = require("resource://devtools/client/shared/sourceeditor/css-autocompleter.js"); 7 8 const CSS_URI = 9 "http://mochi.test:8888/browser/devtools/client/shared/sourceeditor" + 10 "/test/css_statemachine_testcases.css"; 11 const TESTS_URI = 12 "http://mochi.test:8888/browser/devtools/client" + 13 "/shared/sourceeditor/test/css_autocompletion_tests.json"; 14 15 const source = read(CSS_URI); 16 const { tests } = JSON.parse(read(TESTS_URI)); 17 18 const TEST_URI = 19 "data:text/html;charset=UTF-8," + 20 encodeURIComponent(` 21 <!DOCTYPE html> 22 <html> 23 <head> 24 <title>CSS State machine tests.</title> 25 <style> 26 #progress { 27 width: 500px; height: 30px; 28 border: 1px solid black; 29 position: relative 30 } 31 #progress div { 32 width: 0%; height: 100%; 33 background: green; 34 position: absolute; 35 z-index: -1; top: 0 36 } 37 #progress.failed div { 38 background: red !important; 39 } 40 #progress.failed:after { 41 content: 'Some tests failed'; 42 color: white 43 } 44 #progress:before { 45 content: 'Running test ' attr(data-progress) ' of ${tests.length}'; 46 color: white; 47 text-shadow: 0 0 2px darkgreen; 48 } 49 </style> 50 </head> 51 <body> 52 <h2>State machine tests for CSS autocompleter.</h2><br> 53 <div id='progress' data-progress='0'> 54 <div></div> 55 </div> 56 <div id='devtools-menu' class='devtools-toolbarbutton'></div> 57 <div id='devtools-toolbarbutton' class='devtools-menulist'></div> 58 <div id='devtools-anotherone'></div> 59 <div id='devtools-yetagain'></div> 60 <div id='devtools-itjustgoeson'></div> 61 <div id='devtools-okstopitnow'></div> 62 <div class='hidden-labels-box devtools-toolbarbutton devtools-menulist'></div> 63 <div class='devtools-menulist'></div> 64 <div class='devtools-menulist'></div>", 65 <tabs class='devtools-toolbarbutton'><tab></tab><tab></tab><tab></tab></tabs><tabs></tabs> 66 <button class='category-name visible'></button> 67 <div class='devtools-toolbarbutton' label='true'> 68 <hbox class='toolbarbutton-menubutton-button'></hbox></div> 69 </body> 70 </html> 71 `); 72 73 let browser; 74 let index = 0; 75 let completer = null; 76 let inspector; 77 78 add_task(async function test() { 79 const tab = await addTab(TEST_URI); 80 browser = tab.linkedBrowser; 81 await runTests(); 82 browser = null; 83 gBrowser.removeCurrentTab(); 84 }); 85 86 async function runTests() { 87 const target = await createAndAttachTargetForTab(gBrowser.selectedTab); 88 inspector = await target.getFront("inspector"); 89 const walker = inspector.walker; 90 const cssPropertiesFront = await target.getFront("cssProperties"); 91 completer = new CSSCompleter({ 92 walker, 93 cssProperties: cssPropertiesFront.cssProperties, 94 }); 95 await checkStateAndMoveOn(); 96 await completer.walker.release(); 97 await target.destroy(); 98 inspector = null; 99 completer = null; 100 } 101 102 async function checkStateAndMoveOn() { 103 if (index == tests.length) { 104 return; 105 } 106 107 const [lineCh, baseExpectedSuggestions, prefSuggestions] = tests[index]; 108 const [line, ch] = lineCh; 109 110 let expectedSuggestions; 111 if (prefSuggestions) { 112 const additional = []; 113 for (const [pref, property] of prefSuggestions) { 114 if (SpecialPowers.getBoolPref(pref)) { 115 additional.push(property); 116 } 117 } 118 expectedSuggestions = baseExpectedSuggestions.concat(additional); 119 expectedSuggestions.sort(); 120 } else { 121 expectedSuggestions = baseExpectedSuggestions; 122 } 123 124 ++index; 125 await SpecialPowers.spawn( 126 browser, 127 [[index, tests.length]], 128 function ([idx, len]) { 129 const progress = content.document.getElementById("progress"); 130 const progressDiv = content.document.querySelector("#progress > div"); 131 progress.dataset.progress = idx; 132 progressDiv.style.width = (100 * idx) / len + "%"; 133 } 134 ); 135 136 const actualSuggestions = await completer.complete(limit(source, lineCh), { 137 line, 138 ch, 139 }); 140 await checkState(expectedSuggestions, actualSuggestions); 141 await checkStateAndMoveOn(); 142 } 143 144 async function checkState(expected, actual) { 145 if (expected.length != actual.length) { 146 ok( 147 false, 148 "Number of suggestions did not match up for state " + 149 index + 150 ". Expected: " + 151 expected.length + 152 ", Actual: " + 153 actual.length 154 ); 155 await SpecialPowers.spawn(browser, [], function () { 156 const progress = content.document.getElementById("progress"); 157 progress.classList.add("failed"); 158 }); 159 return; 160 } 161 162 for (let i = 0; i < actual.length; i++) { 163 if (expected[i] != actual[i].label) { 164 ok( 165 false, 166 "Suggestion " + 167 i + 168 " of state " + 169 index + 170 " did not match up" + 171 ". Expected: " + 172 expected[i] + 173 ". Actual: " + 174 actual[i].label 175 ); 176 return; 177 } 178 } 179 ok(true, "Test " + index + " passed. "); 180 }