diff --git a/devtools/client/shared/components/AutoCompletePopup.js b/devtools/client/shared/components/AutoCompletePopup.js index 0b2197ee135c..fe4d1a068c60 100644 --- a/devtools/client/shared/components/AutoCompletePopup.js +++ b/devtools/client/shared/components/AutoCompletePopup.js @@ -51,7 +51,7 @@ class AutocompletePopup extends Component { computeState({ autocompleteProvider, filter }) { let list = autocompleteProvider(filter); - let selectedIndex = list.length == 1 ? 0 : -1; + let selectedIndex = list.length > 0 ? 0 : -1; return { list, selectedIndex }; } diff --git a/devtools/client/shared/components/test/mochitest/test_searchbox-with-autocomplete.html b/devtools/client/shared/components/test/mochitest/test_searchbox-with-autocomplete.html index 95a896ff659b..5b6c28937776 100644 --- a/devtools/client/shared/components/test/mochitest/test_searchbox-with-autocomplete.html +++ b/devtools/client/shared/components/test/mochitest/test_searchbox-with-autocomplete.html @@ -26,15 +26,19 @@ window.onload = async function () { * compared with the reference item's value as a test * * @params {Node} - Node to be compared - * @reference {array} - Reference array for comparison + * @reference {array} - Reference array for comparison. The selected index is + * highlighted as a single element array ie. ["[abc]", "ab", "abcPQR"], + * Here the element "abc" is highlighted */ function compareAutocompleteList(list, reference) { - let items = [...list.children].map(el => el.textContent); - for (let i = 0; i < items.length; i++) { - let item = items[i]; - let ref = reference[i]; - is(item, ref, `Item ${i} in list is correct`); - } + const delimiter = " - "; + const observedList = [...list.children].map(el => { + return el.classList.contains("autocomplete-selected") + ? `[${el.textContent}]` + : el.textContent + }); + is(observedList.join(delimiter), reference.join(delimiter), + "Autocomplete items are rendered as expected"); } let React = browserRequire("devtools/client/shared/vendor/react"); @@ -96,7 +100,7 @@ window.onload = async function () { await forceRender(component); compareAutocompleteList($(".devtools-autocomplete-listbox"), [ - "ABC", + "[ABC]", "a1", "a2", "a3", @@ -105,8 +109,6 @@ window.onload = async function () { "abc", ]); - is(refs.autocomplete.state.selectedIndex, -1, "Initialised selectedIndex is -1"); - // Blur event $(".devtools-searchinput").blur(); await forceRender(component); @@ -121,35 +123,84 @@ window.onload = async function () { // ArrowDown synthesizeKey("KEY_ArrowDown"); await forceRender(component); - is(refs.autocomplete.state.selectedIndex, 0, "selectedIndex is 0"); - ok($(".devtools-autocomplete-listbox .autocomplete-item:nth-child(1)") + compareAutocompleteList($(".devtools-autocomplete-listbox"), [ + "ABC", + "[a1]", + "a2", + "a3", + "a4", + "a5", + "abc", + ]); + ok($(".devtools-autocomplete-listbox .autocomplete-item:nth-child(2)") .className.includes("autocomplete-selected"), "Selection class applied"); - // ArrowUp should roll back to the bottom of the list + // A double ArrowUp should roll back to the bottom of the list + synthesizeKey("KEY_ArrowUp"); synthesizeKey("KEY_ArrowUp"); await forceRender(component); - is(refs.autocomplete.state.selectedIndex, 6, "ArrowUp works"); + compareAutocompleteList($(".devtools-autocomplete-listbox"), [ + "ABC", + "a1", + "a2", + "a3", + "a4", + "a5", + "[abc]", + ]); // PageDown should take -5 places up synthesizeKey("KEY_PageUp"); await forceRender(component); - is(refs.autocomplete.state.selectedIndex, 1, "PageUp works"); + compareAutocompleteList($(".devtools-autocomplete-listbox"), [ + "ABC", + "[a1]", + "a2", + "a3", + "a4", + "a5", + "abc", + ]); // PageDown should take +5 places down synthesizeKey("KEY_PageDown"); await forceRender(component); - is(refs.autocomplete.state.selectedIndex, 6, "PageDown works"); + compareAutocompleteList($(".devtools-autocomplete-listbox"), [ + "ABC", + "a1", + "a2", + "a3", + "a4", + "a5", + "[abc]", + ]); // Home should take to the top of the list synthesizeKey("KEY_Home"); await forceRender(component); - is(refs.autocomplete.state.selectedIndex, 0, "Home works"); + compareAutocompleteList($(".devtools-autocomplete-listbox"), [ + "[ABC]", + "a1", + "a2", + "a3", + "a4", + "a5", + "abc", + ]); // End should take to the bottom of the list synthesizeKey("KEY_End"); await forceRender(component); - is(refs.autocomplete.state.selectedIndex, 6, "End works"); + compareAutocompleteList($(".devtools-autocomplete-listbox"), [ + "ABC", + "a1", + "a2", + "a3", + "a4", + "a5", + "[abc]", + ]); // Key down in existing state should rollover to the top synthesizeKey("KEY_ArrowDown"); @@ -164,7 +215,10 @@ window.onload = async function () { synthesizeKey("KEY_Backspace"); await forceRender(component); ok($(".devtools-autocomplete-popup"), "Popup is up"); - compareAutocompleteList($(".devtools-autocomplete-listbox"), ["ABC", "abc"]); + compareAutocompleteList($(".devtools-autocomplete-listbox"), [ + "[ABC]", + "abc" + ]); // Enter key selection synthesizeKey("KEY_ArrowUp"); @@ -212,7 +266,10 @@ window.onload = async function () { // Test for string "pqr ab" which should show list of ABC, abc sendString(" ab"); await forceRender(component); - compareAutocompleteList($(".devtools-autocomplete-listbox"), ["ABC", "abc"]); + compareAutocompleteList($(".devtools-autocomplete-listbox"), [ + "[ABC]", + "abc" + ]); // Select the first element, value now should be "pqr ABC" synthesizeMouseAtCenter(