189 lines
5.9 KiB
JavaScript
189 lines
5.9 KiB
JavaScript
/* Any copyright is dedicated to the Public Domain.
|
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
/* eslint no-unused-vars: [2, {"vars": "local", "args": "none"}] */
|
|
/* import-globals-from head.js */
|
|
|
|
"use strict";
|
|
|
|
/**
|
|
* Helper methods for the HTMLTooltip integration tests.
|
|
*/
|
|
|
|
const HTML_NS = "http://www.w3.org/1999/xhtml";
|
|
const {
|
|
editableField,
|
|
} = require("resource://devtools/client/shared/inplace-editor.js");
|
|
const { colorUtils } = require("resource://devtools/shared/css/color.js");
|
|
|
|
/**
|
|
* Create an inplace editor linked to a span element and click on the span to
|
|
* to turn to edit mode.
|
|
*
|
|
* @param {Object} options
|
|
* Options passed to the InplaceEditor/editableField constructor.
|
|
* @param {Document} doc
|
|
* Document where the span element will be created.
|
|
* @param {String} textContent
|
|
* (optional) String that will be used as the text content of the span.
|
|
*/
|
|
const createInplaceEditorAndClick = async function (options, doc, textContent) {
|
|
const span = (options.element = createSpan(doc));
|
|
if (textContent) {
|
|
span.textContent = textContent;
|
|
}
|
|
|
|
info("Creating an inplace-editor field");
|
|
editableField(options);
|
|
|
|
info("Clicking on the inplace-editor field to turn to edit mode");
|
|
span.click();
|
|
};
|
|
|
|
/**
|
|
* Helper to create a span in the provided document.
|
|
*
|
|
* @param {Document} doc
|
|
* Document where the span element will be created.
|
|
* @return {Element} the created span element.
|
|
*/
|
|
function createSpan(doc) {
|
|
info("Creating a new span element");
|
|
const div = doc.createElementNS(HTML_NS, "div");
|
|
const span = doc.createElementNS(HTML_NS, "span");
|
|
span.setAttribute("tabindex", "0");
|
|
span.style.fontSize = "11px";
|
|
span.style.display = "inline-block";
|
|
span.style.width = "100px";
|
|
span.style.border = "1px solid red";
|
|
span.style.fontFamily = "monospace";
|
|
|
|
div.style.height = "100%";
|
|
div.style.position = "absolute";
|
|
div.appendChild(span);
|
|
|
|
const parent = doc.querySelector("window") || doc.body;
|
|
parent.appendChild(div);
|
|
return span;
|
|
}
|
|
|
|
/**
|
|
* Test helper simulating a key event in an InplaceEditor and checking that the
|
|
* autocompletion works as expected.
|
|
*
|
|
* @param {Array} testData
|
|
* - {String|Object} key, the key to send. An object can be passed with a `key` property.
|
|
* The other properties will be the options for the event (e.g. `shiftKey`)
|
|
* - {String} completion, the expected value of the auto-completion
|
|
* - {Number} index, the index of the selected suggestion in the popup
|
|
* - {Number|Array} items, the number of suggestions in the popup, or, alternatively
|
|
* an array of the items label
|
|
* - {String} postLabel, the expected post label for the selected suggestion
|
|
* - {Boolean} colorSwatch, if there is a swatch of color expected to be visible
|
|
* - {Boolean} noSuggestion, true if the keypress doesn't trigger an "after-suggest" event
|
|
* @param {InplaceEditor} editor
|
|
* The InplaceEditor instance being tested
|
|
*/
|
|
async function testCompletion(
|
|
[key, completion, index, items, postLabel, colorSwatch, noSuggestion],
|
|
editor
|
|
) {
|
|
let eventOptions = {};
|
|
if (typeof key === "object") {
|
|
({ key, ...eventOptions } = key);
|
|
}
|
|
|
|
info(`Pressing key <${key}> | options: ${JSON.stringify(eventOptions)}`);
|
|
info("Expecting " + completion);
|
|
|
|
let onVisibilityChange = null;
|
|
const total = Array.isArray(items) ? items.length : items;
|
|
const open = total > 0;
|
|
if (editor.popup.isOpen != open) {
|
|
onVisibilityChange = editor.popup.once(
|
|
open ? "popup-opened" : "popup-closed"
|
|
);
|
|
}
|
|
|
|
let onSuggest;
|
|
if (/(left|right|back_space|escape)/gi.test(key) || noSuggestion) {
|
|
info("Waiting for next keypress event");
|
|
onSuggest = once(editor.input, "keypress");
|
|
} else {
|
|
info("Waiting for after-suggest event on the editor");
|
|
onSuggest = editor.once("after-suggest");
|
|
}
|
|
|
|
info("Synthesizing key " + key);
|
|
EventUtils.synthesizeKey(key, eventOptions, editor.input.defaultView);
|
|
|
|
await onSuggest;
|
|
await onVisibilityChange;
|
|
await waitForTime(5);
|
|
|
|
info("Checking the state");
|
|
if (completion !== null) {
|
|
is(editor.input.value, completion, "Correct value is autocompleted");
|
|
}
|
|
|
|
if (postLabel) {
|
|
const selectedItem = editor.popup.getItems()[index];
|
|
const selectedElement = editor.popup.elements.get(selectedItem);
|
|
ok(
|
|
selectedElement.textContent.includes(postLabel),
|
|
"Selected popup element contains the expected post-label"
|
|
);
|
|
|
|
// Determines if there is a color swatch attached to the label
|
|
// and if the color swatch's background color matches the post label
|
|
const swatchSpan = selectedElement.getElementsByClassName(
|
|
"autocomplete-swatch autocomplete-colorswatch"
|
|
);
|
|
if (colorSwatch) {
|
|
Assert.strictEqual(
|
|
swatchSpan.length,
|
|
1,
|
|
"Displayed the expected color swatch"
|
|
);
|
|
const color = new colorUtils.CssColor(
|
|
swatchSpan[0].style.backgroundColor
|
|
);
|
|
const swatchColor = color.rgba;
|
|
const postColor = new colorUtils.CssColor(postLabel).rgba;
|
|
Assert.equal(
|
|
swatchColor,
|
|
postColor,
|
|
"Color swatch matches postLabel value"
|
|
);
|
|
} else {
|
|
Assert.strictEqual(
|
|
swatchSpan.length,
|
|
0,
|
|
"As expected no swatches were available"
|
|
);
|
|
}
|
|
}
|
|
|
|
if (total === 0) {
|
|
ok(!(editor.popup && editor.popup.isOpen), "Popup is closed");
|
|
} else {
|
|
ok(editor.popup.isOpen, "Popup is open");
|
|
const popupItems = editor.popup.getItems();
|
|
if (Array.isArray(items)) {
|
|
Assert.deepEqual(
|
|
popupItems.map(item => item.label),
|
|
items,
|
|
"Suggestions match"
|
|
);
|
|
} else {
|
|
is(
|
|
popupItems.length,
|
|
total,
|
|
"Number of suggestions match" +
|
|
(popupItems.length !== total
|
|
? ` - got ${JSON.stringify(popupItems.map(item => item.label))}`
|
|
: "")
|
|
);
|
|
}
|
|
is(editor.popup.selectedIndex, index, "Expected item is selected");
|
|
}
|
|
}
|