зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1614738, remove racy promiseContentSearchChange function in favour of a version that adds the listener first before performing the engine modification action, r=adw
This fixes intermittent test failures that occur more frequently with the JSWindowActor based content search module. Depends on D68237 Differential Revision: https://phabricator.services.mozilla.com/D70619 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
1351306d5f
Коммит
349e62fa06
|
@ -7,75 +7,83 @@ ignoreAllUncaughtExceptions();
|
||||||
add_task(async function() {
|
add_task(async function() {
|
||||||
info("Check POST search engine support");
|
info("Check POST search engine support");
|
||||||
|
|
||||||
await BrowserTestUtils.withNewTab({ gBrowser, url: "about:home" }, function(
|
let currEngine = await Services.search.getDefault();
|
||||||
browser
|
|
||||||
) {
|
|
||||||
return new Promise(resolve => {
|
|
||||||
let searchObserver = async function search_observer(
|
|
||||||
subject,
|
|
||||||
topic,
|
|
||||||
data
|
|
||||||
) {
|
|
||||||
let currEngine = await Services.search.getDefault();
|
|
||||||
let engine = subject.QueryInterface(Ci.nsISearchEngine);
|
|
||||||
info("Observer: " + data + " for " + engine.name);
|
|
||||||
|
|
||||||
if (data != "engine-added") {
|
await BrowserTestUtils.withNewTab(
|
||||||
return;
|
{ gBrowser, url: "about:home" },
|
||||||
}
|
async browser => {
|
||||||
|
let observerPromise = new Promise(resolve => {
|
||||||
|
let searchObserver = async function search_observer(
|
||||||
|
subject,
|
||||||
|
topic,
|
||||||
|
data
|
||||||
|
) {
|
||||||
|
let engine = subject.QueryInterface(Ci.nsISearchEngine);
|
||||||
|
info("Observer: " + data + " for " + engine.name);
|
||||||
|
|
||||||
if (engine.name != "POST Search") {
|
if (data != "engine-added") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Services.obs.removeObserver(
|
if (engine.name != "POST Search") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Services.obs.removeObserver(
|
||||||
|
searchObserver,
|
||||||
|
"browser-search-engine-modified"
|
||||||
|
);
|
||||||
|
|
||||||
|
resolve(engine);
|
||||||
|
};
|
||||||
|
|
||||||
|
Services.obs.addObserver(
|
||||||
searchObserver,
|
searchObserver,
|
||||||
"browser-search-engine-modified"
|
"browser-search-engine-modified"
|
||||||
);
|
);
|
||||||
|
});
|
||||||
|
|
||||||
// Ready to execute the tests!
|
let engine;
|
||||||
let needle = "Search for something awesome.";
|
await promiseContentSearchChange(browser, async () => {
|
||||||
|
Services.search.addEngine(
|
||||||
|
"http://test:80/browser/browser/base/content/test/about/POSTSearchEngine.xml",
|
||||||
|
null,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
await Promise.all([
|
engine = await observerPromise;
|
||||||
promiseContentSearchChange(browser, engine.name),
|
Services.search.setDefault(engine);
|
||||||
Services.search.setDefault(engine),
|
return engine.name;
|
||||||
]);
|
});
|
||||||
let promise = BrowserTestUtils.browserLoaded(browser);
|
|
||||||
await SpecialPowers.spawn(browser, [{ needle }], async function(args) {
|
|
||||||
let doc = content.document;
|
|
||||||
let el = doc.querySelector(["#searchText", "#newtab-search-text"]);
|
|
||||||
el.value = args.needle;
|
|
||||||
doc.getElementById("searchSubmit").click();
|
|
||||||
});
|
|
||||||
|
|
||||||
await promise;
|
// Ready to execute the tests!
|
||||||
|
let needle = "Search for something awesome.";
|
||||||
|
|
||||||
// When the search results load, check them for correctness.
|
let promise = BrowserTestUtils.browserLoaded(browser);
|
||||||
await SpecialPowers.spawn(browser, [{ needle }], async function(args) {
|
await SpecialPowers.spawn(browser, [{ needle }], async function(args) {
|
||||||
let loadedText = content.document.body.textContent;
|
let doc = content.document;
|
||||||
ok(loadedText, "search page loaded");
|
let el = doc.querySelector(["#searchText", "#newtab-search-text"]);
|
||||||
is(
|
el.value = args.needle;
|
||||||
loadedText,
|
doc.getElementById("searchSubmit").click();
|
||||||
"searchterms=" + escape(args.needle.replace(/\s/g, "+")),
|
});
|
||||||
"Search text should arrive correctly"
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
await Services.search.setDefault(currEngine);
|
await promise;
|
||||||
try {
|
|
||||||
await Services.search.removeEngine(engine);
|
// When the search results load, check them for correctness.
|
||||||
} catch (ex) {}
|
await SpecialPowers.spawn(browser, [{ needle }], async function(args) {
|
||||||
resolve();
|
let loadedText = content.document.body.textContent;
|
||||||
};
|
ok(loadedText, "search page loaded");
|
||||||
Services.obs.addObserver(
|
is(
|
||||||
searchObserver,
|
loadedText,
|
||||||
"browser-search-engine-modified"
|
"searchterms=" + escape(args.needle.replace(/\s/g, "+")),
|
||||||
);
|
"Search text should arrive correctly"
|
||||||
Services.search.addEngine(
|
);
|
||||||
"http://test:80/browser/browser/base/content/test/about/POSTSearchEngine.xml",
|
});
|
||||||
null,
|
|
||||||
false
|
await Services.search.setDefault(currEngine);
|
||||||
);
|
try {
|
||||||
});
|
await Services.search.removeEngine(engine);
|
||||||
});
|
} catch (ex) {}
|
||||||
|
}
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
|
@ -12,10 +12,13 @@ add_task(async function() {
|
||||||
async function(browser) {
|
async function(browser) {
|
||||||
// Add a test engine that provides suggestions and switch to it.
|
// Add a test engine that provides suggestions and switch to it.
|
||||||
let currEngine = await Services.search.getDefault();
|
let currEngine = await Services.search.getDefault();
|
||||||
let engine = await promiseNewEngine("searchSuggestionEngine.xml");
|
|
||||||
let p = promiseContentSearchChange(browser, engine.name);
|
let engine;
|
||||||
await Services.search.setDefault(engine);
|
await promiseContentSearchChange(browser, async () => {
|
||||||
await p;
|
engine = await promiseNewEngine("searchSuggestionEngine.xml");
|
||||||
|
await Services.search.setDefault(engine);
|
||||||
|
return engine.name;
|
||||||
|
});
|
||||||
|
|
||||||
// Clear any search history results
|
// Clear any search history results
|
||||||
await new Promise((resolve, reject) => {
|
await new Promise((resolve, reject) => {
|
||||||
|
|
|
@ -13,11 +13,13 @@ add_task(async function() {
|
||||||
async function(browser) {
|
async function(browser) {
|
||||||
// Add a test engine that provides suggestions and switch to it.
|
// Add a test engine that provides suggestions and switch to it.
|
||||||
let currEngine = await Services.search.getDefault();
|
let currEngine = await Services.search.getDefault();
|
||||||
let engine = await promiseNewEngine("searchSuggestionEngine.xml");
|
|
||||||
await Promise.all([
|
let engine;
|
||||||
promiseContentSearchChange(browser, engine.name),
|
await promiseContentSearchChange(browser, async () => {
|
||||||
Services.search.setDefault(engine),
|
engine = await promiseNewEngine("searchSuggestionEngine.xml");
|
||||||
]);
|
await Services.search.setDefault(engine);
|
||||||
|
return engine.name;
|
||||||
|
});
|
||||||
|
|
||||||
await SpecialPowers.spawn(browser, [], async function() {
|
await SpecialPowers.spawn(browser, [], async function() {
|
||||||
// Type an X in the search input.
|
// Type an X in the search input.
|
||||||
|
|
|
@ -13,17 +13,19 @@ add_task(async function() {
|
||||||
{ gBrowser, url: "about:home" },
|
{ gBrowser, url: "about:home" },
|
||||||
async function(browser) {
|
async function(browser) {
|
||||||
let currEngine = await Services.search.getDefault();
|
let currEngine = await Services.search.getDefault();
|
||||||
let engine = await promiseNewEngine("searchSuggestionEngine.xml");
|
|
||||||
|
let engine;
|
||||||
|
await promiseContentSearchChange(browser, async () => {
|
||||||
|
engine = await promiseNewEngine("searchSuggestionEngine.xml");
|
||||||
|
await Services.search.setDefault(engine);
|
||||||
|
return engine.name;
|
||||||
|
});
|
||||||
|
|
||||||
// Make this actually work in healthreport by giving it an ID:
|
// Make this actually work in healthreport by giving it an ID:
|
||||||
Object.defineProperty(engine.wrappedJSObject, "identifier", {
|
Object.defineProperty(engine.wrappedJSObject, "identifier", {
|
||||||
value: "org.mozilla.testsearchsuggestions",
|
value: "org.mozilla.testsearchsuggestions",
|
||||||
});
|
});
|
||||||
|
|
||||||
await Promise.all([
|
|
||||||
promiseContentSearchChange(browser, engine.name),
|
|
||||||
Services.search.setDefault(engine),
|
|
||||||
]);
|
|
||||||
|
|
||||||
await SpecialPowers.spawn(
|
await SpecialPowers.spawn(
|
||||||
browser,
|
browser,
|
||||||
[{ expectedName: engine.name }],
|
[{ expectedName: engine.name }],
|
||||||
|
|
|
@ -158,28 +158,56 @@ function promiseTabLoadEvent(tab, url) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wait for the search engine to change.
|
* Wait for the search engine to change. searchEngineChangeFn is a function
|
||||||
|
* that will be called to change the search engine.
|
||||||
*/
|
*/
|
||||||
function promiseContentSearchChange(browser, newEngineName) {
|
async function promiseContentSearchChange(browser, searchEngineChangeFn) {
|
||||||
// Callers of this depend on very specific, very racy timing, and fail
|
// Add an event listener manually then perform the action, rather than using
|
||||||
// if we introduce the trip through SpecialPowersParent that
|
// BrowserTestUtils.addContentEventListener as that doesn't add the listener
|
||||||
// SpecialPowers.spawn requires.
|
// early enough.
|
||||||
return ContentTask.spawn(browser, { newEngineName }, async function(args) {
|
await SpecialPowers.spawn(browser, [], async () => {
|
||||||
return new Promise(resolve => {
|
// Store the results in a temporary place.
|
||||||
content.addEventListener("ContentSearchService", function listener(
|
content._searchDetails = {
|
||||||
aEvent
|
defaultEnginesList: [],
|
||||||
) {
|
listener: event => {
|
||||||
if (
|
if (event.detail.type == "CurrentState") {
|
||||||
aEvent.detail.type == "CurrentState" &&
|
content._searchDetails.defaultEnginesList.push(
|
||||||
content.wrappedJSObject.gContentSearchController.defaultEngine.name ==
|
content.wrappedJSObject.gContentSearchController.defaultEngine.name
|
||||||
args.newEngineName
|
);
|
||||||
) {
|
|
||||||
content.removeEventListener("ContentSearchService", listener);
|
|
||||||
resolve();
|
|
||||||
}
|
}
|
||||||
});
|
},
|
||||||
});
|
};
|
||||||
|
|
||||||
|
// Listen using the system group to ensure that it fires after
|
||||||
|
// the default behaviour.
|
||||||
|
content.addEventListener(
|
||||||
|
"ContentSearchService",
|
||||||
|
content._searchDetails.listener,
|
||||||
|
{ mozSystemGroup: true }
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let expectedEngineName = await searchEngineChangeFn();
|
||||||
|
|
||||||
|
await SpecialPowers.spawn(
|
||||||
|
browser,
|
||||||
|
[expectedEngineName],
|
||||||
|
async expectedEngineNameChild => {
|
||||||
|
await ContentTaskUtils.waitForCondition(
|
||||||
|
() =>
|
||||||
|
content._searchDetails.defaultEnginesList &&
|
||||||
|
content._searchDetails.defaultEnginesList[
|
||||||
|
content._searchDetails.defaultEnginesList.length - 1
|
||||||
|
] == expectedEngineNameChild
|
||||||
|
);
|
||||||
|
content.removeEventListener(
|
||||||
|
"ContentSearchService",
|
||||||
|
content._searchDetails.listener,
|
||||||
|
{ mozSystemGroup: true }
|
||||||
|
);
|
||||||
|
delete content._searchDetails;
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Загрузка…
Ссылка в новой задаче