Bug 1890689 accumulate input in LargerReceiverBlockSizeThanDesiredBuffering GTest...
[gecko.git] / devtools / client / shared / test / helper_inplace_editor.js
bloba7e544f7083bf23545be6e723f27f746670f0902
1 /* Any copyright is dedicated to the Public Domain.
2    http://creativecommons.org/publicdomain/zero/1.0/ */
3 /* eslint no-unused-vars: [2, {"vars": "local", "args": "none"}] */
4 /* import-globals-from head.js */
6 "use strict";
8 /**
9  * Helper methods for the HTMLTooltip integration tests.
10  */
12 const HTML_NS = "http://www.w3.org/1999/xhtml";
13 const {
14   editableField,
15 } = require("resource://devtools/client/shared/inplace-editor.js");
16 const { colorUtils } = require("resource://devtools/shared/css/color.js");
18 /**
19  * Create an inplace editor linked to a span element and click on the span to
20  * to turn to edit mode.
21  *
22  * @param {Object} options
23  *        Options passed to the InplaceEditor/editableField constructor.
24  * @param {Document} doc
25  *        Document where the span element will be created.
26  * @param {String} textContent
27  *        (optional) String that will be used as the text content of the span.
28  */
29 const createInplaceEditorAndClick = async function (options, doc, textContent) {
30   const span = (options.element = createSpan(doc));
31   if (textContent) {
32     span.textContent = textContent;
33   }
35   info("Creating an inplace-editor field");
36   editableField(options);
38   info("Clicking on the inplace-editor field to turn to edit mode");
39   span.click();
42 /**
43  * Helper to create a span in the provided document.
44  *
45  * @param {Document} doc
46  *        Document where the span element will be created.
47  * @return {Element} the created span element.
48  */
49 function createSpan(doc) {
50   info("Creating a new span element");
51   const div = doc.createElementNS(HTML_NS, "div");
52   const span = doc.createElementNS(HTML_NS, "span");
53   span.setAttribute("tabindex", "0");
54   span.style.fontSize = "11px";
55   span.style.display = "inline-block";
56   span.style.width = "100px";
57   span.style.border = "1px solid red";
58   span.style.fontFamily = "monospace";
60   div.style.height = "100%";
61   div.style.position = "absolute";
62   div.appendChild(span);
64   const parent = doc.querySelector("window") || doc.body;
65   parent.appendChild(div);
66   return span;
69 /**
70  * Test helper simulating a key event in an InplaceEditor and checking that the
71  * autocompletion works as expected.
72  *
73  * @param {Array} testData
74  *        - {String} key, the key to send
75  *        - {String} completion, the expected value of the auto-completion
76  *        - {Number} index, the index of the selected suggestion in the popup
77  *        - {Number} total, the total number of suggestions in the popup
78  *        - {String} postLabel, the expected post label for the selected suggestion
79  *        - {Boolean} colorSwatch, if there is a swatch of color expected to be visible
80  * @param {InplaceEditor} editor
81  *        The InplaceEditor instance being tested
82  */
83 async function testCompletion(
84   [key, completion, index, total, postLabel, colorSwatch],
85   editor
86 ) {
87   info("Pressing key " + key);
88   info("Expecting " + completion);
90   let onVisibilityChange = null;
91   const open = total > 0;
92   if (editor.popup.isOpen != open) {
93     onVisibilityChange = editor.popup.once(
94       open ? "popup-opened" : "popup-closed"
95     );
96   }
98   let onSuggest;
99   if (/(left|right|back_space|escape)/gi.test(key)) {
100     info("Adding event listener for right|back_space|escape keys");
101     onSuggest = once(editor.input, "keypress");
102   } else {
103     info("Waiting for after-suggest event on the editor");
104     onSuggest = editor.once("after-suggest");
105   }
107   info("Synthesizing key " + key);
108   EventUtils.synthesizeKey(key, {}, editor.input.defaultView);
110   await onSuggest;
111   await onVisibilityChange;
112   await waitForTime(5);
114   info("Checking the state");
115   if (completion !== null) {
116     is(editor.input.value, completion, "Correct value is autocompleted");
117   }
119   if (postLabel) {
120     const selectedItem = editor.popup.getItems()[index];
121     const selectedElement = editor.popup.elements.get(selectedItem);
122     ok(
123       selectedElement.textContent.includes(postLabel),
124       "Selected popup element contains the expected post-label"
125     );
127     // Determines if there is a color swatch attached to the label
128     // and if the color swatch's background color matches the post label
129     const swatchSpan = selectedElement.getElementsByClassName(
130       "autocomplete-swatch autocomplete-colorswatch"
131     );
132     if (colorSwatch) {
133       Assert.strictEqual(
134         swatchSpan.length,
135         1,
136         "Displayed the expected color swatch"
137       );
138       const color = new colorUtils.CssColor(
139         swatchSpan[0].style.backgroundColor
140       );
141       const swatchColor = color.rgba;
142       const postColor = new colorUtils.CssColor(postLabel).rgba;
143       Assert.equal(
144         swatchColor,
145         postColor,
146         "Color swatch matches postLabel value"
147       );
148     } else {
149       Assert.strictEqual(
150         swatchSpan.length,
151         0,
152         "As expected no swatches were available"
153       );
154     }
155   }
157   if (total === 0) {
158     ok(!(editor.popup && editor.popup.isOpen), "Popup is closed");
159   } else {
160     ok(editor.popup.isOpen, "Popup is open");
161     is(editor.popup.getItems().length, total, "Number of suggestions match");
162     is(editor.popup.selectedIndex, index, "Expected item is selected");
163   }