1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/mobile/android/base/tests/AboutHomeTest.java Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,303 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +package org.mozilla.gecko.tests; 1.9 + 1.10 +import java.util.ArrayList; 1.11 + 1.12 +import org.mozilla.gecko.Actions; 1.13 + 1.14 +import android.support.v4.view.ViewPager; 1.15 +import android.text.TextUtils; 1.16 +import android.view.View; 1.17 +import android.view.ViewGroup; 1.18 +import android.widget.ListAdapter; 1.19 +import android.widget.ListView; 1.20 +import android.widget.TabWidget; 1.21 +import android.widget.TextView; 1.22 + 1.23 +import com.jayway.android.robotium.solo.Condition; 1.24 + 1.25 +/** 1.26 + * This class is an extension of BaseTest that helps with interaction with about:home 1.27 + * This class contains methods that access the different tabs from about:home, methods that get information like history and bookmarks from the database, edit and remove bookmarks and history items 1.28 + * The purpose of this class is to collect all the logically connected methods that deal with about:home 1.29 + * To use any of these methods in your test make sure it extends AboutHomeTest instead of BaseTest 1.30 + */ 1.31 +abstract class AboutHomeTest extends PixelTest { 1.32 + protected enum AboutHomeTabs {HISTORY, MOST_RECENT, TABS_FROM_LAST_TIME, TOP_SITES, BOOKMARKS, READING_LIST}; 1.33 + private ArrayList<String> aboutHomeTabs = new ArrayList<String>() {{ 1.34 + add("TOP_SITES"); 1.35 + add("BOOKMARKS"); 1.36 + add("READING_LIST"); 1.37 + }}; 1.38 + 1.39 + 1.40 + @Override 1.41 + public void setUp() throws Exception { 1.42 + super.setUp(); 1.43 + 1.44 + if (aboutHomeTabs.size() < 4) { 1.45 + // Update it for tablets vs. phones. 1.46 + if (mDevice.type.equals("phone")) { 1.47 + aboutHomeTabs.add(0, AboutHomeTabs.HISTORY.toString()); 1.48 + } else { 1.49 + aboutHomeTabs.add(AboutHomeTabs.HISTORY.toString()); 1.50 + } 1.51 + } 1.52 + } 1.53 + 1.54 + /** 1.55 + * FIXME: Write new versions of these methods and update their consumers to use the new about:home pages. 1.56 + */ 1.57 + protected ListView getHistoryList(String waitText, int expectedChildCount) { 1.58 + return null; 1.59 + } 1.60 + protected ListView getHistoryList(String waitText) { 1.61 + return null; 1.62 + } 1.63 + 1.64 + // Returns true if the bookmark is displayed in the bookmarks tab, false otherwise - does not check in folders 1.65 + protected void isBookmarkDisplayed(final String url) { 1.66 + boolean isCorrect = waitForTest(new BooleanTest() { 1.67 + @Override 1.68 + public boolean test() { 1.69 + View bookmark = getDisplayedBookmark(url); 1.70 + return bookmark != null; 1.71 + } 1.72 + }, MAX_WAIT_MS); 1.73 + 1.74 + mAsserter.ok(isCorrect, "Checking that " + url + " displayed as a bookmark", url + " displayed"); 1.75 + } 1.76 + 1.77 + // Loads a bookmark by tapping on the bookmark view in the Bookmarks tab 1.78 + protected void loadBookmark(String url) { 1.79 + View bookmark = getDisplayedBookmark(url); 1.80 + if (bookmark != null) { 1.81 + Actions.EventExpecter contentEventExpecter = mActions.expectGeckoEvent("DOMContentLoaded"); 1.82 + mSolo.clickOnView(bookmark); 1.83 + contentEventExpecter.blockForEvent(); 1.84 + contentEventExpecter.unregisterListener(); 1.85 + } else { 1.86 + mAsserter.ok(false, url + " is not one of the displayed bookmarks", "Please make sure the url provided is bookmarked"); 1.87 + } 1.88 + } 1.89 + 1.90 + // Opens the bookmark context menu by long-tapping on it 1.91 + protected void openBookmarkContextMenu(String url) { 1.92 + View bookmark = getDisplayedBookmark(url); 1.93 + if (bookmark != null) { 1.94 + mSolo.waitForView(bookmark); 1.95 + mSolo.clickLongOnView(bookmark, LONG_PRESS_TIME); 1.96 + mSolo.waitForDialogToOpen(); 1.97 + } else { 1.98 + mAsserter.ok(false, url + " is not one of the displayed bookmarks", "Please make sure the url provided is bookmarked"); 1.99 + } 1.100 + } 1.101 + 1.102 + // @return the View associated with bookmark for the provided url or null if the link is not bookmarked 1.103 + protected View getDisplayedBookmark(String url) { 1.104 + openAboutHomeTab(AboutHomeTabs.BOOKMARKS); 1.105 + mSolo.hideSoftKeyboard(); 1.106 + getInstrumentation().waitForIdleSync(); 1.107 + ListView bookmarksTabList = findListViewWithTag("bookmarks"); 1.108 + waitForNonEmptyListToLoad(bookmarksTabList); 1.109 + ListAdapter adapter = bookmarksTabList.getAdapter(); 1.110 + if (adapter != null) { 1.111 + for (int i = 0; i < adapter.getCount(); i++ ) { 1.112 + // I am unable to click the view taken with getView for some reason so getting the child at i 1.113 + bookmarksTabList.smoothScrollToPosition(i); 1.114 + View bookmarkView = bookmarksTabList.getChildAt(i); 1.115 + if (bookmarkView instanceof android.widget.LinearLayout) { 1.116 + ViewGroup bookmarkItemView = (ViewGroup) bookmarkView; 1.117 + for (int j = 0 ; j < bookmarkItemView.getChildCount(); j++) { 1.118 + View bookmarkContent = bookmarkItemView.getChildAt(j); 1.119 + if (bookmarkContent instanceof android.widget.LinearLayout) { 1.120 + ViewGroup bookmarkItemLayout = (ViewGroup) bookmarkContent; 1.121 + for (int k = 0 ; k < bookmarkItemLayout.getChildCount(); k++) { 1.122 + // Both the title and url are represented as text views so we can cast the view without any issues 1.123 + TextView bookmarkTextContent = (TextView)bookmarkItemLayout.getChildAt(k); 1.124 + if (url.equals(bookmarkTextContent.getText().toString())) { 1.125 + return bookmarkView; 1.126 + } 1.127 + } 1.128 + } 1.129 + } 1.130 + } 1.131 + } 1.132 + } 1.133 + return null; 1.134 + } 1.135 + 1.136 + /** 1.137 + * Waits for the given ListView to have a non-empty adapter and be populated 1.138 + * with a minimum number of items. 1.139 + * 1.140 + * This method will return false if the given ListView or its adapter is null, 1.141 + * or if the ListView does not have the minimum number of items. 1.142 + */ 1.143 + protected boolean waitForListToLoad(final ListView listView, final int minSize) { 1.144 + Condition listWaitCondition = new Condition() { 1.145 + @Override 1.146 + public boolean isSatisfied() { 1.147 + if (listView == null) { 1.148 + return false; 1.149 + } 1.150 + 1.151 + final ListAdapter adapter = listView.getAdapter(); 1.152 + if (adapter == null) { 1.153 + return false; 1.154 + } 1.155 + 1.156 + return (listView.getCount() - listView.getHeaderViewsCount() >= minSize); 1.157 + } 1.158 + }; 1.159 + return waitForCondition(listWaitCondition, MAX_WAIT_MS); 1.160 + } 1.161 + 1.162 + protected boolean waitForNonEmptyListToLoad(final ListView listView) { 1.163 + return waitForListToLoad(listView, 1); 1.164 + } 1.165 + 1.166 + /** 1.167 + * Get an active ListView with the specified tag . 1.168 + * 1.169 + * This method uses the predefined tags in HomePager. 1.170 + */ 1.171 + protected final ListView findListViewWithTag(String tag) { 1.172 + for (ListView listView : mSolo.getCurrentViews(ListView.class)) { 1.173 + final String listTag = (String) listView.getTag(); 1.174 + if (TextUtils.isEmpty(listTag)) { 1.175 + continue; 1.176 + } 1.177 + 1.178 + if (TextUtils.equals(listTag, tag)) { 1.179 + return listView; 1.180 + } 1.181 + } 1.182 + 1.183 + return null; 1.184 + } 1.185 + 1.186 + // A wait in order for the about:home tab to be rendered after drag/tab selection 1.187 + private void waitForAboutHomeTab(final int tabIndex) { 1.188 + boolean correctTab = waitForCondition(new Condition() { 1.189 + @Override 1.190 + public boolean isSatisfied() { 1.191 + ViewPager pager = (ViewPager)mSolo.getView(ViewPager.class, 0); 1.192 + return (pager.getCurrentItem() == tabIndex); 1.193 + } 1.194 + }, MAX_WAIT_MS); 1.195 + mAsserter.ok(correctTab, "Checking that the correct tab is displayed", "The " + aboutHomeTabs.get(tabIndex) + " tab is displayed"); 1.196 + } 1.197 + 1.198 + private void clickAboutHomeTab(AboutHomeTabs tab) { 1.199 + mSolo.clickOnText(tab.toString().replace("_", " ")); 1.200 + } 1.201 + 1.202 + /** 1.203 + * Swipes to an about:home tab. 1.204 + * @param int swipeVector Value and direction to swipe (go left for negative, right for positive). 1.205 + */ 1.206 + private void swipeAboutHome(int swipeVector) { 1.207 + // Increase swipe width, which will especially impact tablets. 1.208 + int swipeWidth = mDriver.getGeckoWidth() - 1; 1.209 + int swipeHeight = mDriver.getGeckoHeight() / 2; 1.210 + 1.211 + if (swipeVector >= 0) { 1.212 + // Emulate swipe motion from right to left. 1.213 + for (int i = 0; i < swipeVector; i++) { 1.214 + mActions.drag(swipeWidth, 0, swipeHeight, swipeHeight); 1.215 + mSolo.sleep(100); 1.216 + } 1.217 + } else { 1.218 + // Emulate swipe motion from left to right. 1.219 + for (int i = 0; i > swipeVector; i--) { 1.220 + mActions.drag(0, swipeWidth, swipeHeight, swipeHeight); 1.221 + mSolo.sleep(100); 1.222 + } 1.223 + } 1.224 + } 1.225 + 1.226 + /** 1.227 + * This method can be used to open the different tabs of about:home. 1.228 + * 1.229 + * @param AboutHomeTabs enum item {MOST_RECENT, TABS_FROM_LAST_TIME, TOP_SITES, BOOKMARKS, READING_LIST} 1.230 + */ 1.231 + protected void openAboutHomeTab(AboutHomeTabs tab) { 1.232 + focusUrlBar(); 1.233 + ViewPager pager = (ViewPager)mSolo.getView(ViewPager.class, 0); 1.234 + final int currentTabIndex = pager.getCurrentItem(); 1.235 + int tabOffset; 1.236 + 1.237 + // Handle tablets by just clicking the visible tab title. 1.238 + if (mDevice.type.equals("tablet")) { 1.239 + if (AboutHomeTabs.MOST_RECENT == tab || AboutHomeTabs.TABS_FROM_LAST_TIME == tab) { 1.240 + tabOffset = aboutHomeTabs.indexOf(AboutHomeTabs.HISTORY.toString()) - currentTabIndex; 1.241 + swipeAboutHome(tabOffset); 1.242 + waitForAboutHomeTab(aboutHomeTabs.indexOf(StringHelper.HISTORY_LABEL)); 1.243 + TabWidget tabwidget = (TabWidget)mSolo.getView(TabWidget.class, 0); 1.244 + 1.245 + switch (tab) { 1.246 + case MOST_RECENT: { 1.247 + mSolo.clickOnView(tabwidget.getChildAt(0)); 1.248 + // We can determine if we are on the MOST_RECENT tab only if pages were first visited during the test 1.249 + mAsserter.ok(waitForText(StringHelper.TODAY_LABEL), "Checking that we are in the most recent tab of about:home", "We are in the most recent tab"); 1.250 + break; 1.251 + } 1.252 + case TABS_FROM_LAST_TIME: { 1.253 + mSolo.clickOnView(tabwidget.getChildAt(1)); 1.254 + mAsserter.ok(waitForText(StringHelper.TABS_FROM_LAST_TIME_LABEL), "Checking that we are in the Tabs from last time tab of about:home", "We are in the Tabs from last time tab"); 1.255 + break; 1.256 + } 1.257 + } 1.258 + } else { 1.259 + clickAboutHomeTab(tab); 1.260 + } 1.261 + return; 1.262 + } 1.263 + 1.264 + // Handle phones (non-tablets). 1.265 + tabOffset = aboutHomeTabs.indexOf(tab.toString()) - currentTabIndex; 1.266 + switch (tab) { 1.267 + case TOP_SITES : { 1.268 + swipeAboutHome(tabOffset); 1.269 + waitForAboutHomeTab(aboutHomeTabs.indexOf(tab.toString())); 1.270 + break; 1.271 + } 1.272 + case BOOKMARKS : { 1.273 + swipeAboutHome(tabOffset); 1.274 + waitForAboutHomeTab(aboutHomeTabs.indexOf(tab.toString())); 1.275 + break; 1.276 + } 1.277 + case MOST_RECENT: { 1.278 + // MOST_RECENT is contained in the HISTORY tab. 1.279 + tabOffset = aboutHomeTabs.indexOf(AboutHomeTabs.HISTORY.toString()) - currentTabIndex; 1.280 + swipeAboutHome(tabOffset); 1.281 + waitForAboutHomeTab(aboutHomeTabs.indexOf(StringHelper.HISTORY_LABEL)); 1.282 + TabWidget tabwidget = (TabWidget)mSolo.getView(TabWidget.class, 0); 1.283 + mSolo.clickOnView(tabwidget.getChildAt(0)); 1.284 + // We can determine if we are on the MOST_RECENT tab only if pages were first visited during the test 1.285 + mAsserter.ok(waitForText(StringHelper.TODAY_LABEL), "Checking that we are in the most recent tab of about:home", "We are in the most recent tab"); 1.286 + break; 1.287 + } 1.288 + case TABS_FROM_LAST_TIME: { 1.289 + // TABS_FROM_LAST_TIME is contained in the HISTORY tab. 1.290 + tabOffset = aboutHomeTabs.indexOf(AboutHomeTabs.HISTORY.toString()) - currentTabIndex; 1.291 + swipeAboutHome(tabOffset); 1.292 + waitForAboutHomeTab(aboutHomeTabs.indexOf(StringHelper.HISTORY_LABEL)); 1.293 + TabWidget tabwidget = (TabWidget)mSolo.getView(TabWidget.class, 0); 1.294 + mSolo.clickOnView(tabwidget.getChildAt(1)); 1.295 + mAsserter.ok(waitForText(StringHelper.TABS_FROM_LAST_TIME_LABEL), "Checking that we are in the Tabs from last time tab of about:home", "We are in the Tabs from last time tab"); 1.296 + break; 1.297 + } 1.298 + case READING_LIST: { 1.299 + swipeAboutHome(tabOffset); 1.300 + waitForAboutHomeTab(aboutHomeTabs.indexOf(tab.toString())); 1.301 + break; 1.302 + } 1.303 + 1.304 + } 1.305 + } 1.306 +}