1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/mobile/android/base/tests/testShareLink.java Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,264 @@ 1.4 +package org.mozilla.gecko.tests; 1.5 + 1.6 +import java.util.ArrayList; 1.7 +import java.util.List; 1.8 + 1.9 +import org.mozilla.gecko.Actions; 1.10 + 1.11 +import android.app.Activity; 1.12 +import android.content.Intent; 1.13 +import android.content.pm.PackageManager; 1.14 +import android.content.pm.ResolveInfo; 1.15 +import android.os.Build; 1.16 +import android.view.View; 1.17 +import android.view.ViewGroup; 1.18 +import android.widget.AbsListView; 1.19 +import android.widget.GridView; 1.20 +import android.widget.ListView; 1.21 +import android.widget.TextView; 1.22 + 1.23 +import com.jayway.android.robotium.solo.Condition; 1.24 + 1.25 +/** 1.26 + * This test covers the opening and content of the Share Link pop-up list 1.27 + * The test opens the Share menu from the app menu, the URL bar, a link context menu and the Awesomescreen tabs 1.28 + */ 1.29 +public class testShareLink extends AboutHomeTest { 1.30 + String url; 1.31 + String urlTitle = "Big Link"; 1.32 + 1.33 + public void testShareLink() { 1.34 + url = getAbsoluteUrl("/robocop/robocop_big_link.html"); 1.35 + ArrayList<String> shareOptions; 1.36 + blockForGeckoReady(); 1.37 + 1.38 + // FIXME: This is a temporary hack workaround for a permissions problem. 1.39 + openAboutHomeTab(AboutHomeTabs.READING_LIST); 1.40 + 1.41 + inputAndLoadUrl(url); 1.42 + verifyPageTitle(urlTitle); // Waiting for page title to ensure the page is loaded 1.43 + 1.44 + selectMenuItem("Share"); 1.45 + if (Build.VERSION.SDK_INT >= 14) { 1.46 + // Check for our own sync in the submenu. 1.47 + waitForText("Sync$"); 1.48 + } else { 1.49 + waitForText("Share via"); 1.50 + } 1.51 + 1.52 + // Get list of current avaliable share activities and verify them 1.53 + shareOptions = getShareOptions(); 1.54 + ArrayList<String> displayedOptions = getShareOptionsList(); 1.55 + for (String option:shareOptions) { 1.56 + // Verify if the option is present in the list of displayed share options 1.57 + mAsserter.ok(optionDisplayed(option, displayedOptions), "Share option found", option); 1.58 + } 1.59 + 1.60 + // Test share from the urlbar context menu 1.61 + mActions.sendSpecialKey(Actions.SpecialKey.BACK); // Close the share menu 1.62 + mSolo.clickLongOnText(urlTitle); 1.63 + verifySharePopup(shareOptions,"urlbar"); 1.64 + 1.65 + // The link has a 60px height, so let's try to hit the middle 1.66 + float top = mDriver.getGeckoTop() + 30 * mDevice.density; 1.67 + float left = mDriver.getGeckoLeft() + mDriver.getGeckoWidth() / 2; 1.68 + mSolo.clickLongOnScreen(left, top); 1.69 + verifySharePopup("Share Link",shareOptions,"Link"); 1.70 + 1.71 + // Test the share popup in the Bookmarks page 1.72 + openAboutHomeTab(AboutHomeTabs.BOOKMARKS); 1.73 + 1.74 + final ListView bookmarksList = findListViewWithTag("bookmarks"); 1.75 + mAsserter.is(waitForNonEmptyListToLoad(bookmarksList), true, "list is properly loaded"); 1.76 + 1.77 + int headerViewsCount = bookmarksList.getHeaderViewsCount(); 1.78 + View bookmarksItem = bookmarksList.getChildAt(headerViewsCount); 1.79 + if (bookmarksItem == null) { 1.80 + mAsserter.dumpLog("no child at index " + headerViewsCount + "; waiting for one..."); 1.81 + Condition listWaitCondition = new Condition() { 1.82 + @Override 1.83 + public boolean isSatisfied() { 1.84 + if (bookmarksList.getChildAt(bookmarksList.getHeaderViewsCount()) == null) 1.85 + return false; 1.86 + return true; 1.87 + } 1.88 + }; 1.89 + waitForCondition(listWaitCondition, MAX_WAIT_MS); 1.90 + headerViewsCount = bookmarksList.getHeaderViewsCount(); 1.91 + bookmarksItem = bookmarksList.getChildAt(headerViewsCount); 1.92 + } 1.93 + 1.94 + mSolo.clickLongOnView(bookmarksItem); 1.95 + verifySharePopup(shareOptions,"bookmarks"); 1.96 + 1.97 + // Prepopulate top sites with history items to overflow tiles. 1.98 + // We are trying to move away from using reflection and doing more black-box testing. 1.99 + inputAndLoadUrl(getAbsoluteUrl("/robocop/robocop_blank_01.html")); 1.100 + inputAndLoadUrl(getAbsoluteUrl("/robocop/robocop_blank_02.html")); 1.101 + inputAndLoadUrl(getAbsoluteUrl("/robocop/robocop_blank_03.html")); 1.102 + inputAndLoadUrl(getAbsoluteUrl("/robocop/robocop_blank_04.html")); 1.103 + if (mDevice.type.equals("tablet")) { 1.104 + // Tablets have more tile spaces to fill. 1.105 + inputAndLoadUrl(getAbsoluteUrl("/robocop/robocop_blank_05.html")); 1.106 + inputAndLoadUrl(getAbsoluteUrl("/robocop/robocop_boxes.html")); 1.107 + inputAndLoadUrl(getAbsoluteUrl("/robocop/robocop_search.html")); 1.108 + inputAndLoadUrl(getAbsoluteUrl("/robocop/robocop_text_page.html")); 1.109 + } 1.110 + 1.111 + // Test the share popup in Top Sites. 1.112 + openAboutHomeTab(AboutHomeTabs.TOP_SITES); 1.113 + 1.114 + // Scroll down a bit so that the top sites list has more items on screen. 1.115 + int width = mDriver.getGeckoWidth(); 1.116 + int height = mDriver.getGeckoHeight(); 1.117 + mActions.drag(width / 2, width / 2, height - 10, height / 2); 1.118 + 1.119 + ListView topSitesList = findListViewWithTag("top_sites"); 1.120 + mAsserter.is(waitForNonEmptyListToLoad(topSitesList), true, "list is properly loaded"); 1.121 + View mostVisitedItem = topSitesList.getChildAt(topSitesList.getHeaderViewsCount()); 1.122 + mSolo.clickLongOnView(mostVisitedItem); 1.123 + verifySharePopup(shareOptions,"top_sites"); 1.124 + 1.125 + // Test the share popup in the Most Recent tab 1.126 + openAboutHomeTab(AboutHomeTabs.MOST_RECENT); 1.127 + 1.128 + ListView mostRecentList = findListViewWithTag("most_recent"); 1.129 + mAsserter.is(waitForNonEmptyListToLoad(mostRecentList), true, "list is properly loaded"); 1.130 + 1.131 + // Getting second child after header views because the first is the "Today" label 1.132 + View mostRecentItem = mostRecentList.getChildAt(mostRecentList.getHeaderViewsCount() + 1); 1.133 + mSolo.clickLongOnView(mostRecentItem); 1.134 + verifySharePopup(shareOptions,"most recent"); 1.135 + } 1.136 + 1.137 + public void verifySharePopup(ArrayList<String> shareOptions, String openedFrom) { 1.138 + verifySharePopup("Share", shareOptions, openedFrom); 1.139 + } 1.140 + 1.141 + public void verifySharePopup(String shareItemText, ArrayList<String> shareOptions, String openedFrom) { 1.142 + waitForText(shareItemText); 1.143 + mSolo.clickOnText(shareItemText); 1.144 + waitForText("Share via"); 1.145 + ArrayList<String> displayedOptions = getSharePopupOption(); 1.146 + for (String option:shareOptions) { 1.147 + // Verify if the option is present in the list of displayed share options 1.148 + mAsserter.ok(optionDisplayed(option, displayedOptions), "Share option for " + openedFrom + (openedFrom.equals("urlbar") ? "" : " item") + " found", option); 1.149 + } 1.150 + mActions.sendSpecialKey(Actions.SpecialKey.BACK); 1.151 + /** 1.152 + * Adding a wait for the page title to make sure the Awesomebar will be dismissed 1.153 + * Because of Bug 712370 the Awesomescreen will be dismissed when the Share Menu is closed 1.154 + * so there is no need for handeling this different depending on where the share menu was invoced from 1.155 + * TODO: Look more into why the delay is needed here now and it was working before 1.156 + */ 1.157 + waitForText(urlTitle); 1.158 + } 1.159 + 1.160 + // Create a SEND intent and get the possible activities offered 1.161 + public ArrayList getShareOptions() { 1.162 + ArrayList<String> shareOptions = new ArrayList(); 1.163 + Activity currentActivity = getActivity(); 1.164 + final Intent shareIntent = new Intent(Intent.ACTION_SEND); 1.165 + shareIntent.putExtra(Intent.EXTRA_TEXT, url); 1.166 + shareIntent.putExtra(Intent.EXTRA_SUBJECT, "Robocop Blank 01"); 1.167 + shareIntent.setType("text/plain"); 1.168 + PackageManager pm = currentActivity.getPackageManager(); 1.169 + List<ResolveInfo> activities = pm.queryIntentActivities(shareIntent, 0); 1.170 + for (ResolveInfo activity : activities) { 1.171 + shareOptions.add(activity.loadLabel(pm).toString()); 1.172 + } 1.173 + return shareOptions; 1.174 + } 1.175 + 1.176 + // Traverse the group of views, adding strings from TextViews to the list. 1.177 + private void getGroupTextViews(ViewGroup group, ArrayList<String> list) { 1.178 + for (int i = 0; i < group.getChildCount(); i++) { 1.179 + View child = group.getChildAt(i); 1.180 + if (child instanceof AbsListView) { 1.181 + getGroupTextViews((AbsListView)child, list); 1.182 + } else if (child instanceof ViewGroup) { 1.183 + getGroupTextViews((ViewGroup)child, list); 1.184 + } else if (child instanceof TextView) { 1.185 + String viewText = ((TextView)child).getText().toString(); 1.186 + if (viewText != null && viewText.length() > 0) { 1.187 + list.add(viewText); 1.188 + } 1.189 + } 1.190 + } 1.191 + } 1.192 + 1.193 + // Traverse the group of views, adding strings from TextViews to the list. 1.194 + // This override is for AbsListView, which has adapters. If adapters are 1.195 + // available, it is better to use them so that child views that are not 1.196 + // yet displayed can be examined. 1.197 + private void getGroupTextViews(AbsListView group, ArrayList<String> list) { 1.198 + for (int i = 0; i < group.getAdapter().getCount(); i++) { 1.199 + View child = group.getAdapter().getView(i, null, group); 1.200 + if (child instanceof AbsListView) { 1.201 + getGroupTextViews((AbsListView)child, list); 1.202 + } else if (child instanceof ViewGroup) { 1.203 + getGroupTextViews((ViewGroup)child, list); 1.204 + } else if (child instanceof TextView) { 1.205 + String viewText = ((TextView)child).getText().toString(); 1.206 + if (viewText != null && viewText.length() > 0) { 1.207 + list.add(viewText); 1.208 + } 1.209 + } 1.210 + } 1.211 + } 1.212 + 1.213 + public ArrayList<String> getSharePopupOption() { 1.214 + ArrayList<String> displayedOptions = new ArrayList(); 1.215 + AbsListView shareMenu = getDisplayedShareList(); 1.216 + getGroupTextViews(shareMenu, displayedOptions); 1.217 + return displayedOptions; 1.218 + } 1.219 + 1.220 + public ArrayList<String> getShareSubMenuOption() { 1.221 + ArrayList<String> displayedOptions = new ArrayList(); 1.222 + AbsListView shareMenu = getDisplayedShareList(); 1.223 + getGroupTextViews(shareMenu, displayedOptions); 1.224 + return displayedOptions; 1.225 + } 1.226 + 1.227 + public ArrayList<String> getShareOptionsList() { 1.228 + if (Build.VERSION.SDK_INT >= 14) { 1.229 + return getShareSubMenuOption(); 1.230 + } else { 1.231 + return getSharePopupOption(); 1.232 + } 1.233 + } 1.234 + 1.235 + private boolean optionDisplayed(String shareOption, ArrayList<String> displayedOptions) { 1.236 + for (String displayedOption: displayedOptions) { 1.237 + if (shareOption.equals(displayedOption)) { 1.238 + return true; 1.239 + } 1.240 + } 1.241 + return false; 1.242 + } 1.243 + 1.244 + private AbsListView mViewGroup; 1.245 + 1.246 + private AbsListView getDisplayedShareList() { 1.247 + mViewGroup = null; 1.248 + boolean success = waitForTest(new BooleanTest() { 1.249 + @Override 1.250 + public boolean test() { 1.251 + ArrayList<View> views = mSolo.getCurrentViews(); 1.252 + for (View view : views) { 1.253 + // List may be displayed in different view formats. 1.254 + // On JB, GridView is common; on ICS-, ListView is common. 1.255 + if (view instanceof ListView || 1.256 + view instanceof GridView) { 1.257 + mViewGroup = (AbsListView)view; 1.258 + return true; 1.259 + } 1.260 + } 1.261 + return false; 1.262 + } 1.263 + }, MAX_WAIT_MS); 1.264 + mAsserter.ok(success,"Got the displayed share options?", "Got the share options view"); 1.265 + return mViewGroup; 1.266 + } 1.267 +}