browser/devtools/styleeditor/test/browser_styleeditor_autocomplete.js

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* vim: set ts=2 et sw=2 tw=80: */
     2 /* Any copyright is dedicated to the Public Domain.
     3    http://creativecommons.org/publicdomain/zero/1.0/ */
     5 const TESTCASE_URI = TEST_BASE + "autocomplete.html";
     6 const MAX_SUGGESTIONS = 15;
     8 // Pref which decides if CSS autocompletion is enabled in Style Editor or not.
     9 const AUTOCOMPLETION_PREF = "devtools.styleeditor.autocompletion-enabled";
    11 const {CSSProperties, CSSValues} = getCSSKeywords();
    13 // Test cases to test that autocompletion works correctly when enabled.
    14 // Format:
    15 // [
    16 //   key,
    17 //   {
    18 //     total: Number of suggestions in the popup (-1 if popup is closed),
    19 //     current: Index of selected suggestion,
    20 //     inserted: 1 to check whether the selected suggestion is inserted into the editor or not,
    21 //     entered: 1 if the suggestion is inserted and finalized
    22 //   }
    23 // ]
    24 let TEST_CASES = [
    25   ['VK_RIGHT'],
    26   ['VK_RIGHT'],
    27   ['VK_RIGHT'],
    28   ['VK_RIGHT'],
    29   ['Ctrl+Space', {total: 1, current: 0}],
    30   ['VK_LEFT'],
    31   ['VK_RIGHT'],
    32   ['VK_DOWN'],
    33   ['VK_RIGHT'],
    34   ['VK_RIGHT'],
    35   ['VK_RIGHT'],
    36   ['Ctrl+Space', { total: getSuggestionNumberFor("font"), current: 0}],
    37   ['VK_END'],
    38   ['VK_RETURN'],
    39   ['b', {total: getSuggestionNumberFor("b"), current: 0}],
    40   ['a', {total: getSuggestionNumberFor("ba"), current: 0}],
    41   ['VK_DOWN', {total: getSuggestionNumberFor("ba"), current: 0, inserted: 1}],
    42   ['VK_TAB', {total: getSuggestionNumberFor("ba"), current: 1, inserted: 1}],
    43   ['VK_RETURN', {current: 1, inserted: 1, entered: 1}],
    44   ['b', {total: getSuggestionNumberFor("background", "b"), current: 0}],
    45   ['l', {total: getSuggestionNumberFor("background", "bl"), current: 0}],
    46   ['VK_TAB', {total: getSuggestionNumberFor("background", "bl"), current: 0, inserted: 1}],
    47   ['VK_DOWN', {total: getSuggestionNumberFor("background", "bl"), current: 1, inserted: 1}],
    48   ['VK_UP', {total: getSuggestionNumberFor("background", "bl"), current: 0, inserted: 1}],
    49   ['VK_TAB', {total: getSuggestionNumberFor("background", "bl"), current: 1, inserted: 1}],
    50   ['VK_TAB', {total: getSuggestionNumberFor("background", "bl"), current: 2, inserted: 1}],
    51   [';'],
    52   ['VK_RETURN'],
    53   ['c', {total: getSuggestionNumberFor("c"), current: 0}],
    54   ['o', {total: getSuggestionNumberFor("co"), current: 0}],
    55   ['VK_RETURN', {current: 0, inserted: 1}],
    56   ['r', {total: getSuggestionNumberFor("color", "r"), current: 0}],
    57   ['VK_RETURN', {current: 0, inserted: 1}],
    58   [';'],
    59   ['VK_LEFT'],
    60   ['VK_RIGHT'],
    61   ['VK_DOWN'],
    62   ['VK_RETURN'],
    63   ['b', {total: 2, current: 0}],
    64   ['u', {total: 1, current: 0}],
    65   ['VK_RETURN', {current: 0, inserted: 1}],
    66   ['{'],
    67   ['VK_HOME'],
    68   ['VK_DOWN'],
    69   ['VK_DOWN'],
    70   ['VK_RIGHT'],
    71   ['VK_RIGHT'],
    72   ['VK_RIGHT'],
    73   ['VK_RIGHT'],
    74   ['VK_RIGHT'],
    75   ['VK_RIGHT'],
    76   ['VK_RIGHT'],
    77   ['VK_RIGHT'],
    78   ['VK_RIGHT'],
    79   ['VK_RIGHT'],
    80   ['Ctrl+Space', {total: 1, current: 0}],
    81 ];
    83 let gEditor;
    84 let gPopup;
    85 let index = 0;
    87 function test()
    88 {
    89   waitForExplicitFinish();
    91   addTabAndOpenStyleEditors(1, testEditorAdded);
    93   content.location = TESTCASE_URI;
    94 }
    96 function testEditorAdded(panel) {
    97   info("Editor added, getting the source editor and starting tests");
    98   panel.UI.editors[0].getSourceEditor().then(editor => {
    99     info("source editor found, starting tests.");
   100     gEditor = editor.sourceEditor;
   101     gPopup = gEditor.getAutocompletionPopup();
   102     waitForFocus(testState, gPanelWindow);
   103   });
   104 }
   106 function testState() {
   107   if (index == TEST_CASES.length) {
   108     testAutocompletionDisabled();
   109     return;
   110   }
   112   let [key, details] = TEST_CASES[index];
   113   let entered;
   114   if (details) {
   115     entered = details.entered;
   116   }
   117   let mods = {};
   119   info("pressing key " + key + " to get result: " +
   120                 JSON.stringify(TEST_CASES[index]) + " for index " + index);
   122   let evt = "after-suggest";
   124   if (key == 'Ctrl+Space') {
   125     key = " ";
   126     mods.accelKey = true;
   127   }
   128   else if (key == "VK_RETURN" && entered) {
   129     evt = "popup-hidden";
   130   }
   131   else if (/(left|right|return|home|end)/ig.test(key) ||
   132            (key == "VK_DOWN" && !gPopup.isOpen)) {
   133     evt = "cursorActivity";
   134   }
   135   else if (key == "VK_TAB" || key == "VK_UP" || key == "VK_DOWN") {
   136     evt = "suggestion-entered";
   137   }
   139   gEditor.once(evt, checkState);
   140   EventUtils.synthesizeKey(key, mods, gPanelWindow);
   141 }
   143 function checkState() {
   144   executeSoon(() => {
   145     let [key, details] = TEST_CASES[index];
   146     details = details || {};
   147     let {total, current, inserted} = details;
   149     if (total != undefined) {
   150       ok(gPopup.isOpen, "Popup is open for index " + index);
   151       is(total, gPopup.itemCount,
   152          "Correct total suggestions for index " + index);
   153       is(current, gPopup.selectedIndex,
   154          "Correct index is selected for index " + index);
   155       if (inserted) {
   156         let { preLabel, label, text } = gPopup.getItemAtIndex(current);
   157         let { line, ch } = gEditor.getCursor();
   158         let lineText = gEditor.getText(line);
   159         is(lineText.substring(ch - text.length, ch), text,
   160            "Current suggestion from the popup is inserted into the editor.");
   161       }
   162     }
   163     else {
   164       ok(!gPopup.isOpen, "Popup is closed for index " + index);
   165       if (inserted) {
   166         let { preLabel, label, text } = gPopup.getItemAtIndex(current);
   167         let { line, ch } = gEditor.getCursor();
   168         let lineText = gEditor.getText(line);
   169         is(lineText.substring(ch - text.length, ch), text,
   170            "Current suggestion from the popup is inserted into the editor.");
   171       }
   172     }
   173     index++;
   174     testState();
   175   });
   176 }
   178 function testAutocompletionDisabled() {
   179   gBrowser.removeCurrentTab();
   181   index = 0;
   182   info("Starting test to check if autocompletion is disabled correctly.")
   183   Services.prefs.setBoolPref(AUTOCOMPLETION_PREF, false);
   185   addTabAndOpenStyleEditors(1, testEditorAddedDisabled);
   187   content.location = TESTCASE_URI;
   188 }
   190 function testEditorAddedDisabled(panel) {
   191   info("Editor added, getting the source editor and starting tests");
   192   panel.UI.editors[0].getSourceEditor().then(editor => {
   193     ok(!editor.sourceEditor.getAutocompletionPopup,
   194        "Autocompletion popup does not exist");
   195     cleanup();
   196   });
   197 }
   199 function cleanup() {
   200   Services.prefs.clearUserPref(AUTOCOMPLETION_PREF);
   201   gEditor = null;
   202   gPopup = null;
   203   finish();
   204 }
   206 /**
   207  * Returns a list of all property names and a map of property name vs possible
   208  * CSS values provided by the Gecko engine.
   209  *
   210  * @return {Object} An object with following properties:
   211  *         - CSSProperties {Array} Array of string containing all the possible
   212  *                         CSS property names.
   213  *         - CSSValues {Object|Map} A map where key is the property name and
   214  *                     value is an array of string containing all the possible
   215  *                     CSS values the property can have.
   216  */
   217 function getCSSKeywords() {
   218   let domUtils = Cc["@mozilla.org/inspector/dom-utils;1"]
   219                    .getService(Ci.inIDOMUtils);
   220   let props = {};
   221   let propNames = domUtils.getCSSPropertyNames(domUtils.INCLUDE_ALIASES);
   222   propNames.forEach(prop => {
   223     props[prop] = domUtils.getCSSValuesForProperty(prop).sort();
   224   });
   225   return {
   226     CSSValues: props,
   227     CSSProperties: propNames.sort()
   228   };
   229 }
   231 /**
   232  * Returns the number of expected suggestions for the given property and value.
   233  * If the value is not null, returns the number of values starting with `value`.
   234  * Returns the number of properties starting with `property` otherwise.
   235  */
   236 function getSuggestionNumberFor(property, value) {
   237   if (value == null) {
   238     return CSSProperties.filter(prop => prop.startsWith(property))
   239                         .slice(0, MAX_SUGGESTIONS).length;
   240   }
   241   return CSSValues[property].filter(val => val.startsWith(value))
   242                             .slice(0, MAX_SUGGESTIONS).length;
   243 }

mercurial