1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/mobile/android/base/tests/testAddSearchEngine.java Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,152 @@ 1.4 +package org.mozilla.gecko.tests; 1.5 + 1.6 +import java.util.ArrayList; 1.7 + 1.8 +import org.json.JSONArray; 1.9 +import org.json.JSONException; 1.10 +import org.json.JSONObject; 1.11 +import org.mozilla.gecko.Actions; 1.12 + 1.13 +import android.widget.ImageView; 1.14 +import android.widget.ListAdapter; 1.15 +import android.widget.ListView; 1.16 + 1.17 +/** 1.18 + * Test adding a search engine from an input field context menu. 1.19 + * 1. Get the number of existing search engines from the SearchEngine:Data event and as displayed in about:home. 1.20 + * 2. Load a page with a text field, open the context menu and add a search engine from the page. 1.21 + * 3. Get the number of search engines after adding the new one and verify it has increased by 1. 1.22 + */ 1.23 +public class testAddSearchEngine extends AboutHomeTest { 1.24 + private final int MAX_WAIT_TEST_MS = 5000; 1.25 + private final String SEARCH_TEXT = "Firefox for Android"; 1.26 + private final String ADD_SEARCHENGINE_OPTION_TEXT = "Add Search Engine"; 1.27 + 1.28 + public void testAddSearchEngine() { 1.29 + String blankPageURL = getAbsoluteUrl(StringHelper.ROBOCOP_BLANK_PAGE_01_URL); 1.30 + String searchEngineURL = getAbsoluteUrl(StringHelper.ROBOCOP_SEARCH_URL); 1.31 + 1.32 + blockForGeckoReady(); 1.33 + int height = mDriver.getGeckoTop() + 150; 1.34 + int width = mDriver.getGeckoLeft() + 150; 1.35 + 1.36 + inputAndLoadUrl(blankPageURL); 1.37 + waitForText(StringHelper.ROBOCOP_BLANK_PAGE_01_TITLE); 1.38 + 1.39 + // Get the searchengine data by clicking the awesomebar - this causes Gecko to send Java the list 1.40 + // of search engines. 1.41 + Actions.EventExpecter searchEngineDataEventExpector = mActions.expectGeckoEvent("SearchEngines:Data"); 1.42 + focusUrlBar(); 1.43 + mActions.sendKeys(SEARCH_TEXT); 1.44 + String eventData = searchEngineDataEventExpector.blockForEventData(); 1.45 + searchEngineDataEventExpector.unregisterListener(); 1.46 + 1.47 + ArrayList<String> searchEngines; 1.48 + try { 1.49 + // Parse the data to get the number of searchengines. 1.50 + searchEngines = getSearchEnginesNames(eventData); 1.51 + } catch (JSONException e) { 1.52 + mAsserter.ok(false, "Fatal exception in testAddSearchEngine while decoding JSON search engine string from Gecko prior to addition of new engine.", e.toString()); 1.53 + return; 1.54 + } 1.55 + final int initialNumSearchEngines = searchEngines.size(); 1.56 + mAsserter.dumpLog("Search Engines list = " + searchEngines.toString()); 1.57 + 1.58 + // Verify that the number of displayed search engines is the same as the one received through the SearchEngines:Data event. 1.59 + verifyDisplayedSearchEnginesCount(initialNumSearchEngines); 1.60 + 1.61 + // Load the page for the search engine to add. 1.62 + inputAndLoadUrl(searchEngineURL); 1.63 + waitForText(StringHelper.ROBOCOP_SEARCH_TITLE); 1.64 + verifyPageTitle(StringHelper.ROBOCOP_SEARCH_TITLE); 1.65 + 1.66 + // Used to long-tap on the search input box for the search engine to add. 1.67 + getInstrumentation().waitForIdleSync(); 1.68 + mAsserter.dumpLog("Long Clicking at width = " + String.valueOf(width) + " and height = " + String.valueOf(height)); 1.69 + mSolo.clickLongOnScreen(width,height); 1.70 + 1.71 + ImageView view = waitForViewWithDescription(ImageView.class, ADD_SEARCHENGINE_OPTION_TEXT); 1.72 + mAsserter.isnot(view, null, "The action mode was opened"); 1.73 + 1.74 + // Add the search engine 1.75 + mSolo.clickOnView(view); 1.76 + waitForText("Cancel"); 1.77 + clickOnButton("OK"); 1.78 + mAsserter.ok(!mSolo.searchText(ADD_SEARCHENGINE_OPTION_TEXT), "Adding the Search Engine", "The add Search Engine pop-up has been closed"); 1.79 + waitForText(StringHelper.ROBOCOP_SEARCH_TITLE); // Make sure the pop-up is closed and we are back at the searchengine page 1.80 + 1.81 + // Load Robocop Blank 1 again to give the time for the searchengine to be added 1.82 + // TODO: This is a potential source of intermittent oranges - it's a race condition! 1.83 + loadUrl(blankPageURL); 1.84 + waitForText(StringHelper.ROBOCOP_BLANK_PAGE_01_TITLE); 1.85 + 1.86 + // Load search engines again and check that the quantity of engines has increased by 1. 1.87 + searchEngineDataEventExpector = mActions.expectGeckoEvent("SearchEngines:Data"); 1.88 + focusUrlBar(); 1.89 + mActions.sendKeys(SEARCH_TEXT); 1.90 + eventData = searchEngineDataEventExpector.blockForEventData(); 1.91 + 1.92 + try { 1.93 + // Parse the data to get the number of searchengines 1.94 + searchEngines = getSearchEnginesNames(eventData); 1.95 + } catch (JSONException e) { 1.96 + mAsserter.ok(false, "Fatal exception in testAddSearchEngine while decoding JSON search engine string from Gecko after adding of new engine.", e.toString()); 1.97 + return; 1.98 + } 1.99 + 1.100 + mAsserter.dumpLog("Search Engines list = " + searchEngines.toString()); 1.101 + mAsserter.is(searchEngines.size(), initialNumSearchEngines + 1, "Checking the number of Search Engines has increased"); 1.102 + 1.103 + // Verify that the number of displayed searchengines is the same as the one received through the SearchEngines:Data event. 1.104 + verifyDisplayedSearchEnginesCount(initialNumSearchEngines + 1); 1.105 + searchEngineDataEventExpector.unregisterListener(); 1.106 + } 1.107 + 1.108 + /** 1.109 + * Helper method to decode a list of search engine names from the provided search engine information 1.110 + * JSON string sent from Gecko. 1.111 + * @param searchEngineData The JSON string representing the search engine array to process 1.112 + * @return An ArrayList<String> containing the names of all the search engines represented in 1.113 + * the provided JSON message. 1.114 + * @throws JSONException In the event that the JSON provided cannot be decoded. 1.115 + */ 1.116 + public ArrayList<String> getSearchEnginesNames(String searchEngineData) throws JSONException { 1.117 + JSONObject data = new JSONObject(searchEngineData); 1.118 + JSONArray engines = data.getJSONArray("searchEngines"); 1.119 + 1.120 + ArrayList<String> searchEngineNames = new ArrayList<String>(); 1.121 + for (int i = 0; i < engines.length(); i++) { 1.122 + JSONObject engineJSON = engines.getJSONObject(i); 1.123 + searchEngineNames.add(engineJSON.getString("name")); 1.124 + } 1.125 + return searchEngineNames; 1.126 + } 1.127 + 1.128 + /** 1.129 + * Method to verify that the displayed number of search engines matches the expected number. 1.130 + * @param expectedCount The expected number of search engines. 1.131 + */ 1.132 + public void verifyDisplayedSearchEnginesCount(final int expectedCount) { 1.133 + mSolo.clearEditText(0); 1.134 + mActions.sendKeys(SEARCH_TEXT); 1.135 + boolean correctNumSearchEnginesDisplayed = waitForTest(new BooleanTest() { 1.136 + @Override 1.137 + public boolean test() { 1.138 + ListView list = findListViewWithTag("browser_search"); 1.139 + if (list == null) { 1.140 + return false; 1.141 + } 1.142 + ListAdapter adapter = list.getAdapter(); 1.143 + if (adapter == null) { 1.144 + return false; 1.145 + } 1.146 + return (adapter.getCount() == expectedCount); 1.147 + } 1.148 + }, MAX_WAIT_TEST_MS); 1.149 + 1.150 + // Exit about:home 1.151 + mActions.sendSpecialKey(Actions.SpecialKey.BACK); 1.152 + waitForText(StringHelper.ROBOCOP_BLANK_PAGE_01_TITLE); 1.153 + mAsserter.ok(correctNumSearchEnginesDisplayed, expectedCount + " Search Engines should be displayed" , "The correct number of Search Engines has been displayed"); 1.154 + } 1.155 +}