Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
1 package org.mozilla.gecko.tests;
3 import java.util.ArrayList;
4 import java.util.List;
6 import org.mozilla.gecko.Actions;
8 import android.app.Activity;
9 import android.content.Intent;
10 import android.content.pm.PackageManager;
11 import android.content.pm.ResolveInfo;
12 import android.os.Build;
13 import android.view.View;
14 import android.view.ViewGroup;
15 import android.widget.AbsListView;
16 import android.widget.GridView;
17 import android.widget.ListView;
18 import android.widget.TextView;
20 import com.jayway.android.robotium.solo.Condition;
22 /**
23 * This test covers the opening and content of the Share Link pop-up list
24 * The test opens the Share menu from the app menu, the URL bar, a link context menu and the Awesomescreen tabs
25 */
26 public class testShareLink extends AboutHomeTest {
27 String url;
28 String urlTitle = "Big Link";
30 public void testShareLink() {
31 url = getAbsoluteUrl("/robocop/robocop_big_link.html");
32 ArrayList<String> shareOptions;
33 blockForGeckoReady();
35 // FIXME: This is a temporary hack workaround for a permissions problem.
36 openAboutHomeTab(AboutHomeTabs.READING_LIST);
38 inputAndLoadUrl(url);
39 verifyPageTitle(urlTitle); // Waiting for page title to ensure the page is loaded
41 selectMenuItem("Share");
42 if (Build.VERSION.SDK_INT >= 14) {
43 // Check for our own sync in the submenu.
44 waitForText("Sync$");
45 } else {
46 waitForText("Share via");
47 }
49 // Get list of current avaliable share activities and verify them
50 shareOptions = getShareOptions();
51 ArrayList<String> displayedOptions = getShareOptionsList();
52 for (String option:shareOptions) {
53 // Verify if the option is present in the list of displayed share options
54 mAsserter.ok(optionDisplayed(option, displayedOptions), "Share option found", option);
55 }
57 // Test share from the urlbar context menu
58 mActions.sendSpecialKey(Actions.SpecialKey.BACK); // Close the share menu
59 mSolo.clickLongOnText(urlTitle);
60 verifySharePopup(shareOptions,"urlbar");
62 // The link has a 60px height, so let's try to hit the middle
63 float top = mDriver.getGeckoTop() + 30 * mDevice.density;
64 float left = mDriver.getGeckoLeft() + mDriver.getGeckoWidth() / 2;
65 mSolo.clickLongOnScreen(left, top);
66 verifySharePopup("Share Link",shareOptions,"Link");
68 // Test the share popup in the Bookmarks page
69 openAboutHomeTab(AboutHomeTabs.BOOKMARKS);
71 final ListView bookmarksList = findListViewWithTag("bookmarks");
72 mAsserter.is(waitForNonEmptyListToLoad(bookmarksList), true, "list is properly loaded");
74 int headerViewsCount = bookmarksList.getHeaderViewsCount();
75 View bookmarksItem = bookmarksList.getChildAt(headerViewsCount);
76 if (bookmarksItem == null) {
77 mAsserter.dumpLog("no child at index " + headerViewsCount + "; waiting for one...");
78 Condition listWaitCondition = new Condition() {
79 @Override
80 public boolean isSatisfied() {
81 if (bookmarksList.getChildAt(bookmarksList.getHeaderViewsCount()) == null)
82 return false;
83 return true;
84 }
85 };
86 waitForCondition(listWaitCondition, MAX_WAIT_MS);
87 headerViewsCount = bookmarksList.getHeaderViewsCount();
88 bookmarksItem = bookmarksList.getChildAt(headerViewsCount);
89 }
91 mSolo.clickLongOnView(bookmarksItem);
92 verifySharePopup(shareOptions,"bookmarks");
94 // Prepopulate top sites with history items to overflow tiles.
95 // We are trying to move away from using reflection and doing more black-box testing.
96 inputAndLoadUrl(getAbsoluteUrl("/robocop/robocop_blank_01.html"));
97 inputAndLoadUrl(getAbsoluteUrl("/robocop/robocop_blank_02.html"));
98 inputAndLoadUrl(getAbsoluteUrl("/robocop/robocop_blank_03.html"));
99 inputAndLoadUrl(getAbsoluteUrl("/robocop/robocop_blank_04.html"));
100 if (mDevice.type.equals("tablet")) {
101 // Tablets have more tile spaces to fill.
102 inputAndLoadUrl(getAbsoluteUrl("/robocop/robocop_blank_05.html"));
103 inputAndLoadUrl(getAbsoluteUrl("/robocop/robocop_boxes.html"));
104 inputAndLoadUrl(getAbsoluteUrl("/robocop/robocop_search.html"));
105 inputAndLoadUrl(getAbsoluteUrl("/robocop/robocop_text_page.html"));
106 }
108 // Test the share popup in Top Sites.
109 openAboutHomeTab(AboutHomeTabs.TOP_SITES);
111 // Scroll down a bit so that the top sites list has more items on screen.
112 int width = mDriver.getGeckoWidth();
113 int height = mDriver.getGeckoHeight();
114 mActions.drag(width / 2, width / 2, height - 10, height / 2);
116 ListView topSitesList = findListViewWithTag("top_sites");
117 mAsserter.is(waitForNonEmptyListToLoad(topSitesList), true, "list is properly loaded");
118 View mostVisitedItem = topSitesList.getChildAt(topSitesList.getHeaderViewsCount());
119 mSolo.clickLongOnView(mostVisitedItem);
120 verifySharePopup(shareOptions,"top_sites");
122 // Test the share popup in the Most Recent tab
123 openAboutHomeTab(AboutHomeTabs.MOST_RECENT);
125 ListView mostRecentList = findListViewWithTag("most_recent");
126 mAsserter.is(waitForNonEmptyListToLoad(mostRecentList), true, "list is properly loaded");
128 // Getting second child after header views because the first is the "Today" label
129 View mostRecentItem = mostRecentList.getChildAt(mostRecentList.getHeaderViewsCount() + 1);
130 mSolo.clickLongOnView(mostRecentItem);
131 verifySharePopup(shareOptions,"most recent");
132 }
134 public void verifySharePopup(ArrayList<String> shareOptions, String openedFrom) {
135 verifySharePopup("Share", shareOptions, openedFrom);
136 }
138 public void verifySharePopup(String shareItemText, ArrayList<String> shareOptions, String openedFrom) {
139 waitForText(shareItemText);
140 mSolo.clickOnText(shareItemText);
141 waitForText("Share via");
142 ArrayList<String> displayedOptions = getSharePopupOption();
143 for (String option:shareOptions) {
144 // Verify if the option is present in the list of displayed share options
145 mAsserter.ok(optionDisplayed(option, displayedOptions), "Share option for " + openedFrom + (openedFrom.equals("urlbar") ? "" : " item") + " found", option);
146 }
147 mActions.sendSpecialKey(Actions.SpecialKey.BACK);
148 /**
149 * Adding a wait for the page title to make sure the Awesomebar will be dismissed
150 * Because of Bug 712370 the Awesomescreen will be dismissed when the Share Menu is closed
151 * so there is no need for handeling this different depending on where the share menu was invoced from
152 * TODO: Look more into why the delay is needed here now and it was working before
153 */
154 waitForText(urlTitle);
155 }
157 // Create a SEND intent and get the possible activities offered
158 public ArrayList getShareOptions() {
159 ArrayList<String> shareOptions = new ArrayList();
160 Activity currentActivity = getActivity();
161 final Intent shareIntent = new Intent(Intent.ACTION_SEND);
162 shareIntent.putExtra(Intent.EXTRA_TEXT, url);
163 shareIntent.putExtra(Intent.EXTRA_SUBJECT, "Robocop Blank 01");
164 shareIntent.setType("text/plain");
165 PackageManager pm = currentActivity.getPackageManager();
166 List<ResolveInfo> activities = pm.queryIntentActivities(shareIntent, 0);
167 for (ResolveInfo activity : activities) {
168 shareOptions.add(activity.loadLabel(pm).toString());
169 }
170 return shareOptions;
171 }
173 // Traverse the group of views, adding strings from TextViews to the list.
174 private void getGroupTextViews(ViewGroup group, ArrayList<String> list) {
175 for (int i = 0; i < group.getChildCount(); i++) {
176 View child = group.getChildAt(i);
177 if (child instanceof AbsListView) {
178 getGroupTextViews((AbsListView)child, list);
179 } else if (child instanceof ViewGroup) {
180 getGroupTextViews((ViewGroup)child, list);
181 } else if (child instanceof TextView) {
182 String viewText = ((TextView)child).getText().toString();
183 if (viewText != null && viewText.length() > 0) {
184 list.add(viewText);
185 }
186 }
187 }
188 }
190 // Traverse the group of views, adding strings from TextViews to the list.
191 // This override is for AbsListView, which has adapters. If adapters are
192 // available, it is better to use them so that child views that are not
193 // yet displayed can be examined.
194 private void getGroupTextViews(AbsListView group, ArrayList<String> list) {
195 for (int i = 0; i < group.getAdapter().getCount(); i++) {
196 View child = group.getAdapter().getView(i, null, group);
197 if (child instanceof AbsListView) {
198 getGroupTextViews((AbsListView)child, list);
199 } else if (child instanceof ViewGroup) {
200 getGroupTextViews((ViewGroup)child, list);
201 } else if (child instanceof TextView) {
202 String viewText = ((TextView)child).getText().toString();
203 if (viewText != null && viewText.length() > 0) {
204 list.add(viewText);
205 }
206 }
207 }
208 }
210 public ArrayList<String> getSharePopupOption() {
211 ArrayList<String> displayedOptions = new ArrayList();
212 AbsListView shareMenu = getDisplayedShareList();
213 getGroupTextViews(shareMenu, displayedOptions);
214 return displayedOptions;
215 }
217 public ArrayList<String> getShareSubMenuOption() {
218 ArrayList<String> displayedOptions = new ArrayList();
219 AbsListView shareMenu = getDisplayedShareList();
220 getGroupTextViews(shareMenu, displayedOptions);
221 return displayedOptions;
222 }
224 public ArrayList<String> getShareOptionsList() {
225 if (Build.VERSION.SDK_INT >= 14) {
226 return getShareSubMenuOption();
227 } else {
228 return getSharePopupOption();
229 }
230 }
232 private boolean optionDisplayed(String shareOption, ArrayList<String> displayedOptions) {
233 for (String displayedOption: displayedOptions) {
234 if (shareOption.equals(displayedOption)) {
235 return true;
236 }
237 }
238 return false;
239 }
241 private AbsListView mViewGroup;
243 private AbsListView getDisplayedShareList() {
244 mViewGroup = null;
245 boolean success = waitForTest(new BooleanTest() {
246 @Override
247 public boolean test() {
248 ArrayList<View> views = mSolo.getCurrentViews();
249 for (View view : views) {
250 // List may be displayed in different view formats.
251 // On JB, GridView is common; on ICS-, ListView is common.
252 if (view instanceof ListView ||
253 view instanceof GridView) {
254 mViewGroup = (AbsListView)view;
255 return true;
256 }
257 }
258 return false;
259 }
260 }, MAX_WAIT_MS);
261 mAsserter.ok(success,"Got the displayed share options?", "Got the share options view");
262 return mViewGroup;
263 }
264 }