Source code

Revision control

Copy as Markdown

Other Tools

Test Info: Errors

/* Any copyright is dedicated to the Public Domain.
/**
* This tests checks that search suggestions can be acted upon correctly
* e.g. selection with modifiers, copying text.
*/
"use strict";
const SUGGEST_URLBAR_PREF = "browser.urlbar.suggest.searches";
const TEST_ENGINE_BASENAME = "searchSuggestionEngine.xml";
const MAX_CHARS_PREF = "browser.urlbar.maxCharsForSearchSuggestions";
// Must run first.
add_task(async function prepare() {
let suggestionsEnabled = Services.prefs.getBoolPref(SUGGEST_URLBAR_PREF);
Services.prefs.setBoolPref(SUGGEST_URLBAR_PREF, true);
await SearchTestUtils.promiseNewSearchEngine({
url: getRootDirectory(gTestPath) + TEST_ENGINE_BASENAME,
setAsDefault: true,
});
await UrlbarTestUtils.formHistory.clear();
registerCleanupFunction(async function () {
Services.prefs.setBoolPref(SUGGEST_URLBAR_PREF, suggestionsEnabled);
// Clicking suggestions causes visits to search results pages, so clear that
// history now.
await PlacesUtils.history.clear();
await UrlbarTestUtils.formHistory.clear();
});
});
add_task(async function clickSuggestion() {
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser);
gURLBar.focus();
await UrlbarTestUtils.promiseAutocompleteResultPopup({
window,
value: "foo",
});
let [idx, suggestion, engineName] = await getFirstSuggestion();
Assert.equal(
engineName,
"browser_searchSuggestionEngine searchSuggestionEngine.xml",
"Expected suggestion engine"
);
let uri = (await Services.search.getDefault()).getSubmission(suggestion).uri;
let loadPromise = BrowserTestUtils.browserLoaded(
gBrowser.selectedBrowser,
false,
uri.spec
);
let element = await UrlbarTestUtils.waitForAutocompleteResultAt(window, idx);
EventUtils.synthesizeMouseAtCenter(element, {}, window);
await loadPromise;
let formHistory = (
await UrlbarTestUtils.formHistory.search({ source: engineName })
).map(entry => entry.value);
Assert.deepEqual(
formHistory,
["foofoo"],
"Should find form history after adding it"
);
BrowserTestUtils.removeTab(tab);
await UrlbarTestUtils.formHistory.clear();
});
async function testPressEnterOnSuggestion(
expectedUrl = null,
keyModifiers = {}
) {
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser);
gURLBar.focus();
await UrlbarTestUtils.promiseAutocompleteResultPopup({
window,
value: "foo",
});
let [idx, suggestion, engineName] = await getFirstSuggestion();
Assert.equal(
engineName,
"browser_searchSuggestionEngine searchSuggestionEngine.xml",
"Expected suggestion engine"
);
let hasExpectedUrl = !!expectedUrl;
if (!expectedUrl) {
expectedUrl = (await Services.search.getDefault()).getSubmission(suggestion)
.uri.spec;
}
let promiseLoad = BrowserTestUtils.waitForDocLoadAndStopIt(
expectedUrl,
gBrowser.selectedBrowser
);
let promiseFormHistory;
if (!hasExpectedUrl) {
promiseFormHistory = UrlbarTestUtils.formHistory.promiseChanged("add");
}
for (let i = 0; i < idx; ++i) {
EventUtils.synthesizeKey("KEY_ArrowDown");
}
EventUtils.synthesizeKey("KEY_Enter", keyModifiers);
await promiseLoad;
if (!hasExpectedUrl) {
await promiseFormHistory;
let formHistory = (
await UrlbarTestUtils.formHistory.search({ source: engineName })
).map(entry => entry.value);
Assert.deepEqual(
formHistory,
["foofoo"],
"Should find form history after adding it"
);
}
BrowserTestUtils.removeTab(tab);
await UrlbarTestUtils.formHistory.clear();
}
add_task(async function plainEnterOnSuggestion() {
await testPressEnterOnSuggestion();
});
add_task(async function ctrlEnterOnSuggestion() {
await testPressEnterOnSuggestion("https://www.foofoo.com/", {
ctrlKey: true,
});
});
add_task(async function copySuggestionText() {
gURLBar.focus();
await UrlbarTestUtils.promiseAutocompleteResultPopup({
window,
value: "foo",
});
let [idx, suggestion] = await getFirstSuggestion();
for (let i = 0; i < idx; ++i) {
EventUtils.synthesizeKey("KEY_ArrowDown");
}
gURLBar.select();
await SimpleTest.promiseClipboardChange(suggestion, () => {
goDoCommand("cmd_copy");
});
});
add_task(async function typeMaxChars() {
gURLBar.focus();
let maxChars = 10;
await SpecialPowers.pushPrefEnv({
set: [[MAX_CHARS_PREF, maxChars]],
});
// Make a string as long as maxChars and type it.
let value = "";
for (let i = 0; i < maxChars; i++) {
value += String.fromCharCode("a".charCodeAt(0) + i);
}
await UrlbarTestUtils.promiseAutocompleteResultPopup({
window,
value,
});
// Suggestions should be fetched since we allow them when typing, and the
// value so far isn't longer than maxChars anyway.
await assertSuggestions([value + "foo", value + "bar"]);
// Now type some additional chars. Suggestions should still be fetched since
// we allow them when typing.
for (let i = 0; i < 3; i++) {
let char = String.fromCharCode("z".charCodeAt(0) - i);
value += char;
EventUtils.synthesizeKey(char);
await assertSuggestions([value + "foo", value + "bar"]);
}
await SpecialPowers.popPrefEnv();
});
add_task(async function pasteMaxChars() {
gURLBar.focus();
let maxChars = 10;
await SpecialPowers.pushPrefEnv({
set: [[MAX_CHARS_PREF, maxChars]],
});
// Make a string as long as maxChars and paste it.
let value = "";
for (let i = 0; i < maxChars; i++) {
value += String.fromCharCode("a".charCodeAt(0) + i);
}
await selectAndPaste(value);
// Suggestions should be fetched since the pasted string is not longer than
// maxChars.
await assertSuggestions([value + "foo", value + "bar"]);
// Now type some additional chars. Suggestions should still be fetched since
// we allow them when typing.
for (let i = 0; i < 3; i++) {
let char = String.fromCharCode("z".charCodeAt(0) - i);
value += char;
EventUtils.synthesizeKey(char);
await assertSuggestions([value + "foo", value + "bar"]);
}
await SpecialPowers.popPrefEnv();
});
add_task(async function pasteMoreThanMaxChars() {
gURLBar.focus();
let maxChars = 10;
await SpecialPowers.pushPrefEnv({
set: [[MAX_CHARS_PREF, maxChars]],
});
// Make a string longer than maxChars and paste it.
let value = "";
for (let i = 0; i < 2 * maxChars; i++) {
value += String.fromCharCode("a".charCodeAt(0) + i);
}
await selectAndPaste(value);
// Suggestions should not be fetched since the value was pasted and it was
// longer than maxChars.
await assertSuggestions([]);
// Now type some additional chars. Suggestions should now be fetched since we
// allow them when typing.
for (let i = 0; i < 3; i++) {
let char = String.fromCharCode("z".charCodeAt(0) - i);
value += char;
EventUtils.synthesizeKey(char);
await assertSuggestions([value + "foo", value + "bar"]);
}
// Paste again. The string is longer than maxChars, so suggestions should not
// be fetched.
await selectAndPaste(value);
await assertSuggestions([]);
await SpecialPowers.popPrefEnv();
});
add_task(async function heuristicAddsFormHistory() {
await UrlbarTestUtils.formHistory.clear();
let formHistory = (await UrlbarTestUtils.formHistory.search()).map(
entry => entry.value
);
Assert.deepEqual(formHistory, [], "Form history should be empty initially");
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser);
gURLBar.focus();
await UrlbarTestUtils.promiseAutocompleteResultPopup({
window,
value: "foo",
});
let result = await UrlbarTestUtils.getDetailsOfResultAt(window, 0);
Assert.ok(result.heuristic);
Assert.equal(result.type, UrlbarUtils.RESULT_TYPE.SEARCH);
Assert.equal(result.searchParams.query, "foo");
let uri = (await Services.search.getDefault()).getSubmission("foo").uri;
let loadPromise = BrowserTestUtils.browserLoaded(
gBrowser.selectedBrowser,
false,
uri.spec
);
let formHistoryPromise = UrlbarTestUtils.formHistory.promiseChanged("add");
let element = await UrlbarTestUtils.waitForAutocompleteResultAt(window, 0);
EventUtils.synthesizeMouseAtCenter(element, {}, window);
await loadPromise;
await formHistoryPromise;
formHistory = (
await UrlbarTestUtils.formHistory.search({
source: result.searchParams.engine,
})
).map(entry => entry.value);
Assert.deepEqual(
formHistory,
["foo"],
"Should find form history after adding it"
);
BrowserTestUtils.removeTab(tab);
await UrlbarTestUtils.formHistory.clear();
});
async function getFirstSuggestion() {
let results = await getSuggestionResults();
if (!results.length) {
return [-1, null, null];
}
let result = results[0];
return [
result.index,
result.searchParams.suggestion,
result.searchParams.engine,
];
}
async function getSuggestionResults() {
await UrlbarTestUtils.promiseSearchComplete(window);
let results = [];
let matchCount = UrlbarTestUtils.getResultCount(window);
for (let i = 0; i < matchCount; i++) {
let result = await UrlbarTestUtils.getDetailsOfResultAt(window, i);
if (
result.type == UrlbarUtils.RESULT_TYPE.SEARCH &&
result.searchParams.suggestion
) {
result.index = i;
results.push(result);
}
}
return results;
}
async function assertSuggestions(expectedSuggestions) {
let results = await getSuggestionResults();
let actualSuggestions = results.map(r => r.searchParams.suggestion);
Assert.deepEqual(
actualSuggestions,
expectedSuggestions,
"Expected suggestions"
);
}