Commit edcd9248 authored by Solomon Kinard's avatar Solomon Kinard Committed by Commit Bot

[Extensions] SearchApiTest tabs.onUpdated() instead of tabs.query().

The purpose of this CL is flake mitigation.

This paragraph relates to running each apitest 3000x apiece.
These are crashes even when the test is only succeed().
The flake rate is around 1.3% with unrelated crashes.
Relevant tests seem to have a similar heuristic.
Dave mentioned it might be good to file a bug for it.

Flakiness may have been caused by instantly checking tab url.
This CL leverages a TabListener object to await tab updates.
Once a tab has been updated, the url can be chekced more reliably.
A queue of depth one was implemented here not expecting more than that.

For the normal test, didPerformQuery cannot be run first/parallel
due to race condition errors where two succeed occur simultaneously
when the test framework was only expecting one, causing error.

These tests pass locally, as did the previous version. The previous
version was run with `--gtest_repeat=20`, in addition to this version.

Bug: 1119846

Change-Id: Idcb3a3aa82e4ce9df7a36da9a69071634c1a6ff1
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2368147
Commit-Queue: Solomon Kinard <solomonkinard@chromium.org>
Reviewed-by: default avatarDavid Bertoni <dbertoni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#802748}
parent 1a37d614
...@@ -13,22 +13,19 @@ namespace { ...@@ -13,22 +13,19 @@ namespace {
using SearchApiTest = ExtensionApiTest; using SearchApiTest = ExtensionApiTest;
// Test various scenarios, such as the use of input different parameters. // Test various scenarios, such as the use of input different parameters.
// Flaky. See crbug.com/1119846. IN_PROC_BROWSER_TEST_F(SearchApiTest, Normal) {
IN_PROC_BROWSER_TEST_F(SearchApiTest, DISABLED_Normal) {
ASSERT_TRUE(RunExtensionTest("search/query/normal")) << message_; ASSERT_TRUE(RunExtensionTest("search/query/normal")) << message_;
} }
// Test incognito browser in extension default spanning mode. // Test incognito browser in extension default spanning mode.
// Flaky. See crbug.com/1119846. IN_PROC_BROWSER_TEST_F(SearchApiTest, Incognito) {
IN_PROC_BROWSER_TEST_F(SearchApiTest, DISABLED_Incognito) {
ResultCatcher catcher; ResultCatcher catcher;
CreateIncognitoBrowser(browser()->profile()); CreateIncognitoBrowser(browser()->profile());
ASSERT_TRUE(RunExtensionTestIncognito("search/query/incognito")) << message_; ASSERT_TRUE(RunExtensionTestIncognito("search/query/incognito")) << message_;
} }
// Test incognito browser in extension split mode. // Test incognito browser in extension split mode.
// Flaky. See crbug.com/1119846. IN_PROC_BROWSER_TEST_F(SearchApiTest, IncognitoSplit) {
IN_PROC_BROWSER_TEST_F(SearchApiTest, DISABLED_IncognitoSplit) {
ResultCatcher catcher; ResultCatcher catcher;
catcher.RestrictToBrowserContext( catcher.RestrictToBrowserContext(
browser()->profile()->GetPrimaryOTRProfile()); browser()->profile()->GetPrimaryOTRProfile());
......
...@@ -9,24 +9,6 @@ var succeed = chrome.test.succeed; ...@@ -9,24 +9,6 @@ var succeed = chrome.test.succeed;
const SEARCH_WORDS = 'search words'; const SEARCH_WORDS = 'search words';
var testHelper = (tabs, queryInfo) => {
assertEq(1, tabs.length);
const tab = tabs[0];
// The browser test should have spun up an incognito browser, which
// should be active.
assertTrue(tab.incognito);
chrome.search.query(queryInfo, () => {
assertNoLastError();
chrome.tabs.query({windowId: tab.windowId}, (tabs) => {
const tab = tabs[0];
const url = new URL(tab.pendingUrl || tab.url);
// The default search is google.
assertEq('www.google.com', url.hostname);
succeed();
});
});
};
chrome.test.runTests([ chrome.test.runTests([
// Verify search results shown in specified incognito tab. // Verify search results shown in specified incognito tab.
...@@ -43,4 +25,33 @@ chrome.test.runTests([ ...@@ -43,4 +25,33 @@ chrome.test.runTests([
testHelper(tabs, {search: SEARCH_WORDS}); testHelper(tabs, {search: SEARCH_WORDS});
}); });
}, },
]); ]);
\ No newline at end of file
var testHelper = (tabs, queryInfo) => {
assertEq(1, tabs.length);
const tab = tabs[0];
// The browser test should have spun up an incognito browser, which
// should be active.
assertTrue(tab.incognito);
addTabListener(tab.id);
chrome.search.query(queryInfo, () => {
assertNoLastError();
chrome.tabs.query({windowId: tab.windowId}, (tabs) => {});
});
};
let addTabListener = (tabIdExpected) => {
chrome.tabs.onUpdated.addListener(function listener(tabId, changeInfo, tab) {
if (tabId != tabIdExpected || changeInfo.status !== 'complete') {
return; // Not our tab.
}
// Note: make sure to stop listening to future events, so that this
// doesn't affect future tests.
chrome.tabs.onUpdated.removeListener(listener);
// The tab finished loading. It should be on google (the default
// search engine).
const hostname = new URL(tab.url).hostname;
assertEq('www.google.com', hostname);
succeed();
});
};
...@@ -29,22 +29,33 @@ if (chrome.extension.inIncognitoContext) { ...@@ -29,22 +29,33 @@ if (chrome.extension.inIncognitoContext) {
}); });
}, },
]); ]);
}
var testHelper = (tabs, queryInfo) => { var testHelper = (tabs, queryInfo) => {
assertEq(1, tabs.length); assertEq(1, tabs.length);
const tab = tabs[0]; const tab = tabs[0];
// The browser test should have spun up an incognito browser, which // The browser test should have spun up an incognito browser, which
// should be active. // should be active.
assertTrue(tab.incognito); assertTrue(tab.incognito);
chrome.search.query(queryInfo, () => { addTabListener(tab.id);
assertNoLastError(); chrome.search.query(queryInfo, () => {
chrome.tabs.query({windowId: tab.windowId}, (tabs) => { assertNoLastError();
const tab = tabs[0]; chrome.tabs.query({windowId: tab.windowId}, (tabs) => {});
const url = new URL(tab.pendingUrl || tab.url); });
// The default search is google. };
assertEq('www.google.com', url.hostname);
succeed(); let addTabListener = (tabIdExpected) => {
}); chrome.tabs.onUpdated.addListener(function listener(tabId, changeInfo, tab) {
}); if (tabId != tabIdExpected || changeInfo.status !== 'complete') {
}; return; // Not our tab.
} }
\ No newline at end of file // Note: make sure to stop listening to future events, so that this
// doesn't affect future tests.
chrome.tabs.onUpdated.removeListener(listener);
// The tab finished loading. It should be on google (the default
// search engine).
const hostname = new URL(tab.url).hostname;
assertEq('www.google.com', hostname);
succeed();
});
};
...@@ -21,22 +21,18 @@ chrome.test.runTests([ ...@@ -21,22 +21,18 @@ chrome.test.runTests([
}); });
}, },
// Display results in current tab if no disposition is provided.
function QueryPopulatedDispositionEmpty() { function QueryPopulatedDispositionEmpty() {
chrome.tabs.query({active: true}, (tabs) => { chrome.tabs.create({}, (tab) => {
chrome.search.query({search: SEARCH_WORDS}, () => { addTabListener(tab.id);
didPerformQuery(tabs[0].id); chrome.search.query({search: SEARCH_WORDS}, () => {});
});
}); });
}, },
// Display results in current tab if said disposition is provided. // Display results in current tab if said disposition is provided.
function QueryPopulatedDispositionCurrentTab() { function QueryPopulatedDispositionCurrentTab() {
chrome.tabs.query({active: true}, (tabs) => { chrome.tabs.create({}, (tab) => {
chrome.search.query( addTabListener(tab.id);
{search: SEARCH_WORDS, disposition: 'CURRENT_TAB'}, () => { chrome.search.query({search: SEARCH_WORDS, disposition: 'CURRENT_TAB'});
didPerformQuery(tabs[0].id);
});
}); });
}, },
...@@ -44,13 +40,13 @@ chrome.test.runTests([ ...@@ -44,13 +40,13 @@ chrome.test.runTests([
function QueryPopulatedDispositionNewTab() { function QueryPopulatedDispositionNewTab() {
chrome.tabs.query({}, (initialTabs) => { chrome.tabs.query({}, (initialTabs) => {
let initialTabIds = initialTabs.map(tab => tab.id); let initialTabIds = initialTabs.map(tab => tab.id);
addAnyTabListener();
chrome.search.query( chrome.search.query(
{search: SEARCH_WORDS, disposition: 'NEW_TAB'}, () => { {search: SEARCH_WORDS, disposition: 'NEW_TAB'}, () => {
chrome.tabs.query({active: true, currentWindow: true}, (tabs) => { chrome.tabs.query({active: true, currentWindow: true}, (tabs) => {
assertEq(1, tabs.length); assertEq(1, tabs.length);
// A new tab should have been created. // A new tab should have been created.
assertFalse(initialTabIds.includes(tabs[0].id)); assertFalse(initialTabIds.includes(tabs[0].id));
didPerformQuery(tabs[0].id);
}); });
}); });
}); });
...@@ -60,6 +56,7 @@ chrome.test.runTests([ ...@@ -60,6 +56,7 @@ chrome.test.runTests([
function QueryPopulatedDispositionNewWindow() { function QueryPopulatedDispositionNewWindow() {
chrome.windows.getAll({}, (initialWindows) => { chrome.windows.getAll({}, (initialWindows) => {
let initialWindowIds = initialWindows.map(window => window.id); let initialWindowIds = initialWindows.map(window => window.id);
addAnyTabListener();
chrome.search.query( chrome.search.query(
{search: SEARCH_WORDS, disposition: 'NEW_WINDOW'}, () => { {search: SEARCH_WORDS, disposition: 'NEW_WINDOW'}, () => {
chrome.windows.getAll({}, (windows) => { chrome.windows.getAll({}, (windows) => {
...@@ -67,9 +64,6 @@ chrome.test.runTests([ ...@@ -67,9 +64,6 @@ chrome.test.runTests([
let window = let window =
windows.find(window => !initialWindowIds.includes(window.id)); windows.find(window => !initialWindowIds.includes(window.id));
assertTrue(!!window); assertTrue(!!window);
chrome.tabs.query({windowId: window.id}, (tabs) => {
didPerformQuery(tabs[0].id);
});
}); });
}); });
}); });
...@@ -78,9 +72,8 @@ chrome.test.runTests([ ...@@ -78,9 +72,8 @@ chrome.test.runTests([
// Display results in specified tab if said tabId is provided. // Display results in specified tab if said tabId is provided.
function QueryPopulatedTabIDValid() { function QueryPopulatedTabIDValid() {
chrome.tabs.create({}, (tab) => { chrome.tabs.create({}, (tab) => {
chrome.search.query({search: SEARCH_WORDS, tabId: tab.id}, () => { addTabListener(tab.id);
didPerformQuery(tab.id); chrome.search.query({search: SEARCH_WORDS, tabId: tab.id});
});
}); });
}, },
...@@ -105,13 +98,23 @@ chrome.test.runTests([ ...@@ -105,13 +98,23 @@ chrome.test.runTests([
}, },
]); ]);
var didPerformQuery = function(tabId) { let addTabListener = (tabIdExpected) => {
assertNoLastError(); chrome.tabs.onUpdated.addListener(function listener(tabId, changeInfo, tab) {
chrome.tabs.get(tabId, (tab) => { if ((tabIdExpected != -1 && tabId != tabIdExpected) ||
const tabUrl = tab.pendingUrl || tab.url; changeInfo.status !== 'complete') {
const url = new URL(tabUrl); return; // Not our tab.
// The default search is google. }
assertEq('www.google.com', url.hostname); // Note: make sure to stop listening to future events, so that this
// doesn't affect future tests.
chrome.tabs.onUpdated.removeListener(listener);
// The tab finished loading. It should be on google (the default
// search engine).
const hostname = new URL(tab.url).hostname;
assertEq('www.google.com', hostname);
succeed(); succeed();
}); });
} };
\ No newline at end of file
let addAnyTabListener = () => {
addTabListener(-1);
};
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment