mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-30 00:01:50 +00:00
Bug 907768 - Rewrite search suggestion test hooks, fix network bypass in SuggestClient. r=bnicholson
This patch fixes all testSearchSuggestions intermittent failures, except for those that appear to be caused by update checks on 2.3. It also replaces all waitForTest (deprecated) calls with waitForCondition.
This commit is contained in:
parent
ea0230fdb7
commit
6adb3eb176
@ -4,19 +4,6 @@
|
||||
|
||||
package org.mozilla.gecko;
|
||||
|
||||
import org.mozilla.gecko.AppConstants;
|
||||
import org.mozilla.gecko.GeckoAppShell;
|
||||
import org.mozilla.gecko.mozglue.RobocopTarget;
|
||||
import org.mozilla.gecko.util.HardwareUtils;
|
||||
|
||||
import org.json.JSONArray;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.NetworkInfo;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@ -25,6 +12,16 @@ import java.net.URL;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.mozilla.gecko.mozglue.RobocopTarget;
|
||||
import org.mozilla.gecko.util.HardwareUtils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.NetworkInfo;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* Use network-based search suggestions.
|
||||
*/
|
||||
@ -52,20 +49,13 @@ public class SuggestClient {
|
||||
private String mPrevQuery;
|
||||
private ArrayList<String> mPrevResults;
|
||||
|
||||
public SuggestClient(Context context, String suggestTemplate, int timeout, int maxResults) {
|
||||
@RobocopTarget
|
||||
public SuggestClient(Context context, String suggestTemplate, int timeout, int maxResults, boolean checkNetwork) {
|
||||
mContext = context;
|
||||
mMaxResults = maxResults;
|
||||
mSuggestTemplate = suggestTemplate;
|
||||
mTimeout = timeout;
|
||||
mCheckNetwork = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* This constructor is used exclusively by Robocop.
|
||||
*/
|
||||
@RobocopTarget
|
||||
public SuggestClient(Context context, String suggestTemplate, int timeout) {
|
||||
this(context, suggestTemplate, timeout, Integer.MAX_VALUE);
|
||||
mCheckNetwork = checkNetwork;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -66,6 +66,26 @@ import android.widget.TextView;
|
||||
*/
|
||||
public class BrowserSearch extends HomeFragment
|
||||
implements GeckoEventListener {
|
||||
|
||||
@RobocopTarget
|
||||
public interface SuggestClientFactory {
|
||||
public SuggestClient getSuggestClient(Context context, String template, int timeout, int max);
|
||||
}
|
||||
|
||||
@RobocopTarget
|
||||
public static class DefaultSuggestClientFactory implements SuggestClientFactory {
|
||||
@Override
|
||||
public SuggestClient getSuggestClient(Context context, String template, int timeout, int max) {
|
||||
return new SuggestClient(context, template, timeout, max, true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set this to mock the suggestion mechanism. Public for access from tests.
|
||||
*/
|
||||
@RobocopTarget
|
||||
public static volatile SuggestClientFactory sSuggestClientFactory = new DefaultSuggestClientFactory();
|
||||
|
||||
// Logging tag name
|
||||
private static final String LOGTAG = "GeckoBrowserSearch";
|
||||
|
||||
@ -104,8 +124,10 @@ public class BrowserSearch extends HomeFragment
|
||||
// The list showing search results
|
||||
private HomeListView mList;
|
||||
|
||||
// Client that performs search suggestion queries
|
||||
private volatile SuggestClient mSuggestClient;
|
||||
// Client that performs search suggestion queries.
|
||||
// Public for testing.
|
||||
@RobocopTarget
|
||||
public volatile SuggestClient mSuggestClient;
|
||||
|
||||
// List of search engines from Gecko.
|
||||
// Do not mutate this list.
|
||||
@ -549,12 +571,8 @@ public class BrowserSearch extends HomeFragment
|
||||
final boolean isPrivate = (tab != null && tab.isPrivate());
|
||||
|
||||
// Only create a new instance of SuggestClient if it hasn't been
|
||||
// set yet. e.g. Robocop tests might set it directly before search
|
||||
// engines are loaded.
|
||||
if (mSuggestClient == null && !isPrivate) {
|
||||
setSuggestClient(new SuggestClient(getActivity(), suggestTemplate,
|
||||
SUGGESTION_TIMEOUT, SUGGESTION_MAX));
|
||||
}
|
||||
// set yet.
|
||||
maybeSetSuggestClient(suggestTemplate, isPrivate);
|
||||
} else {
|
||||
searchEngines.add(engine);
|
||||
}
|
||||
@ -579,18 +597,12 @@ public class BrowserSearch extends HomeFragment
|
||||
filterSuggestions();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the private SuggestClient instance. Should only be called if the suggestClient is
|
||||
* null (i.e. has not yet been initialized or has been nulled). Non-private access is
|
||||
* for testing purposes only.
|
||||
*/
|
||||
@RobocopTarget
|
||||
public void setSuggestClient(final SuggestClient client) {
|
||||
if (mSuggestClient != null) {
|
||||
throw new IllegalStateException("Can only set the SuggestClient if it has not " +
|
||||
"yet been initialized!");
|
||||
private void maybeSetSuggestClient(final String suggestTemplate, final boolean isPrivate) {
|
||||
if (mSuggestClient != null || isPrivate) {
|
||||
return;
|
||||
}
|
||||
mSuggestClient = client;
|
||||
|
||||
mSuggestClient = sSuggestClientFactory.getSuggestClient(getActivity(), suggestTemplate, SUGGESTION_TIMEOUT, SUGGESTION_MAX);
|
||||
}
|
||||
|
||||
private void showSuggestionsOptIn() {
|
||||
|
@ -3,17 +3,17 @@ package org.mozilla.gecko.tests;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
import org.mozilla.gecko.Actions;
|
||||
import org.mozilla.gecko.R;
|
||||
import org.mozilla.gecko.SuggestClient;
|
||||
import org.mozilla.gecko.home.BrowserSearch;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.content.Context;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.jayway.android.robotium.solo.Condition;
|
||||
|
||||
/**
|
||||
* Test for search suggestions.
|
||||
* Sends queries from AwesomeBar input and verifies that suggestions match
|
||||
@ -21,11 +21,17 @@ import android.widget.TextView;
|
||||
*/
|
||||
public class testSearchSuggestions extends BaseTest {
|
||||
private static final int SUGGESTION_MAX = 3;
|
||||
private static final int SUGGESTION_TIMEOUT = 5000;
|
||||
private static final int SUGGESTION_TIMEOUT = 15000;
|
||||
|
||||
private static final String TEST_QUERY = "foo barz";
|
||||
private static final String SUGGESTION_TEMPLATE = "/robocop/robocop_suggestions.sjs?query=__searchTerms__";
|
||||
|
||||
public void testSearchSuggestions() {
|
||||
// Mock the search system.
|
||||
// The BrowserSearch UI only shows up once a non-empty
|
||||
// search term is entered, but we swizzle in a new factory beforehand.
|
||||
mockSuggestClientFactory();
|
||||
|
||||
blockForGeckoReady();
|
||||
|
||||
// Map of expected values. See robocop_suggestions.sjs.
|
||||
@ -34,43 +40,44 @@ public class testSearchSuggestions extends BaseTest {
|
||||
|
||||
focusUrlBar();
|
||||
|
||||
// At this point we rely on our swizzling having worked -- which relies
|
||||
// on us not having previously run a search.
|
||||
// The test will fail later if there's already a BrowserSearch object with a
|
||||
// suggest client set, so fail here.
|
||||
BrowserSearch browserSearch = (BrowserSearch) getBrowserSearch();
|
||||
mAsserter.ok(browserSearch == null ||
|
||||
browserSearch.mSuggestClient == null,
|
||||
"There is no existing search client.", "");
|
||||
|
||||
// Now test the incremental suggestions.
|
||||
for (int i = 0; i < TEST_QUERY.length(); i++) {
|
||||
Actions.EventExpecter enginesEventExpecter = null;
|
||||
|
||||
if (i == 0) {
|
||||
enginesEventExpecter = mActions.expectGeckoEvent("SearchEngines:Data");
|
||||
}
|
||||
|
||||
mActions.sendKeys(TEST_QUERY.substring(i, i+1));
|
||||
|
||||
// The BrowserSearch UI only shows up once a non-empty
|
||||
// search term is entered
|
||||
if (enginesEventExpecter != null) {
|
||||
connectSuggestClient(getActivity());
|
||||
enginesEventExpecter.blockForEvent();
|
||||
enginesEventExpecter.unregisterListener();
|
||||
enginesEventExpecter = null;
|
||||
}
|
||||
|
||||
final String query = TEST_QUERY.substring(0, i+1);
|
||||
mSolo.waitForView(R.id.suggestion_text);
|
||||
boolean success = waitForTest(new BooleanTest() {
|
||||
boolean success = waitForCondition(new Condition() {
|
||||
@Override
|
||||
public boolean test() {
|
||||
// get the first suggestion row
|
||||
public boolean isSatisfied() {
|
||||
// Get the first suggestion row.
|
||||
ViewGroup suggestionGroup = (ViewGroup) getActivity().findViewById(R.id.suggestion_layout);
|
||||
if (suggestionGroup == null)
|
||||
if (suggestionGroup == null) {
|
||||
mAsserter.dumpLog("Fail: suggestionGroup is null.");
|
||||
return false;
|
||||
}
|
||||
|
||||
ArrayList<String> expected = suggestMap.get(query);
|
||||
final ArrayList<String> expected = suggestMap.get(query);
|
||||
for (int i = 0; i < expected.size(); i++) {
|
||||
View queryChild = suggestionGroup.getChildAt(i);
|
||||
if (queryChild == null || queryChild.getVisibility() == View.GONE)
|
||||
if (queryChild == null || queryChild.getVisibility() == View.GONE) {
|
||||
mAsserter.dumpLog("Fail: queryChild is null or GONE.");
|
||||
return false;
|
||||
}
|
||||
|
||||
String suggestion = ((TextView) queryChild.findViewById(R.id.suggestion_text)).getText().toString();
|
||||
if (!suggestion.equals(expected.get(i)))
|
||||
if (!suggestion.equals(expected.get(i))) {
|
||||
mAsserter.dumpLog("Suggestion '" + suggestion + "' not equal to expected '" + expected.get(i) + "'.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -93,21 +100,16 @@ public class testSearchSuggestions extends BaseTest {
|
||||
suggestMap.put("foo barz", new ArrayList<String>() {{ add("foo barz"); }});
|
||||
}
|
||||
|
||||
private void connectSuggestClient(final Activity activity) {
|
||||
waitForTest(new BooleanTest() {
|
||||
private void mockSuggestClientFactory() {
|
||||
BrowserSearch.sSuggestClientFactory = new BrowserSearch.SuggestClientFactory() {
|
||||
@Override
|
||||
public boolean test() {
|
||||
final Fragment browserSearch = getBrowserSearch();
|
||||
return (browserSearch != null);
|
||||
public SuggestClient getSuggestClient(Context context, String template, int timeout, int max) {
|
||||
final String suggestTemplate = getAbsoluteRawUrl(SUGGESTION_TEMPLATE);
|
||||
|
||||
// This one uses our template, and also doesn't check for network accessibility.
|
||||
return new SuggestClient(context, suggestTemplate, SUGGESTION_TIMEOUT, Integer.MAX_VALUE, false);
|
||||
}
|
||||
}, SUGGESTION_TIMEOUT);
|
||||
|
||||
final BrowserSearch browserSearch = (BrowserSearch) getBrowserSearch();
|
||||
|
||||
final String suggestTemplate = getAbsoluteRawUrl(SUGGESTION_TEMPLATE);
|
||||
final SuggestClient client = new SuggestClient(activity, suggestTemplate,
|
||||
SUGGESTION_TIMEOUT);
|
||||
browserSearch.setSuggestClient(client);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -133,7 +133,7 @@ public class SuggestionsFragment extends Fragment {
|
||||
|
||||
public void setEngine(SearchEngine engine) {
|
||||
suggestClient = new SuggestClient(getActivity(), engine.getSuggestionTemplate(GECKO_SEARCH_TERMS_URL_PARAM),
|
||||
SUGGESTION_TIMEOUT, SUGGESTION_MAX);
|
||||
SUGGESTION_TIMEOUT, SUGGESTION_MAX, true);
|
||||
}
|
||||
|
||||
public void loadSuggestions(String query) {
|
||||
|
Loading…
Reference in New Issue
Block a user