|
1 package org.mozilla.gecko.tests; |
|
2 |
|
3 import java.util.ArrayList; |
|
4 import java.util.Arrays; |
|
5 import java.util.HashMap; |
|
6 import java.util.List; |
|
7 import java.util.Map; |
|
8 import java.util.Map.Entry; |
|
9 |
|
10 import org.mozilla.gecko.Actions; |
|
11 import org.mozilla.gecko.AppConstants; |
|
12 |
|
13 /** This patch tests the Sections present in the Settings Menu and the |
|
14 * default values for them |
|
15 */ |
|
16 public class testSettingsMenuItems extends PixelTest { |
|
17 String BRAND_NAME = "(Fennec|Nightly|Aurora|Firefox|Firefox Beta)"; |
|
18 |
|
19 /** |
|
20 * The following String[][] (arrays) match the menu hierarchy for each section. |
|
21 * Each String[] (array) represents the menu items/choices in the following order: |
|
22 * |
|
23 * itemTitle { defaultValue [options] } |
|
24 * |
|
25 * where defaultValue is optional, and there can be multiple options. |
|
26 * |
|
27 * These menu items are the ones that are always present - to test menu items that differ |
|
28 * based on build (e.g., release vs. nightly), add the items in <code>addConditionalSettings</code>. |
|
29 */ |
|
30 |
|
31 // Customize menu items. |
|
32 String[] PATH_CUSTOMIZE = { "Customize" }; |
|
33 String[][] OPTIONS_CUSTOMIZE = { |
|
34 { "Home" }, |
|
35 { "Search", "", "Show search suggestions", "Installed search engines"}, |
|
36 { "Tabs", "Don't restore after quitting " + BRAND_NAME, "Always restore", "Don't restore after quitting " + BRAND_NAME }, |
|
37 { "Import from Android", "", "Bookmarks", "History", "Import" }, |
|
38 }; |
|
39 |
|
40 // Home panel menu items. |
|
41 String[] PATH_HOME = { "Customize", "Home" }; |
|
42 String[][] OPTIONS_HOME = { |
|
43 { "Panels" }, |
|
44 { "Automatic updates", "Enabled", "Enabled", "Only over Wi-Fi" }, |
|
45 }; |
|
46 |
|
47 // Display menu items. |
|
48 String[] PATH_DISPLAY = { "Display" }; |
|
49 String[][] OPTIONS_DISPLAY = { |
|
50 { "Text size" }, |
|
51 { "Title bar", "Show page title", "Show page title", "Show page address" }, |
|
52 { "Advanced" }, |
|
53 { "Character encoding", "Don't show menu", "Show menu", "Don't show menu" }, |
|
54 { "Plugins", "Tap to play", "Enabled", "Tap to play", "Disabled" }, |
|
55 }; |
|
56 |
|
57 // Privacy menu items. |
|
58 String[] PATH_PRIVACY = { "Privacy" }; |
|
59 String[][] OPTIONS_PRIVACY = { |
|
60 { "Tracking", "Do not tell sites anything about my tracking preferences", "Tell sites that I do not want to be tracked", "Tell sites that I want to be tracked", "Do not tell sites anything about my tracking preferences" }, |
|
61 { "Cookies", "Enabled", "Enabled, excluding 3rd party", "Disabled" }, |
|
62 { "Remember passwords" }, |
|
63 { "Use master password" }, |
|
64 { "Clear private data", "", "Browsing history", "Downloads", "Form & search history", "Cookies & active logins", "Saved passwords", "Cache", "Offline website data", "Site settings", "Clear data" }, |
|
65 }; |
|
66 |
|
67 // Mozilla/vendor menu items. |
|
68 String[] PATH_MOZILLA = { "Mozilla" }; |
|
69 String[][] OPTIONS_MOZILLA = { |
|
70 { "About " + BRAND_NAME }, |
|
71 { "FAQs" }, |
|
72 { "Give feedback" }, |
|
73 { "Show product announcements" }, |
|
74 { "Data choices" }, |
|
75 { BRAND_NAME + " Health Report", "Shares data with Mozilla about your browser health and helps you understand your browser performance" }, |
|
76 { "View my Health Report" }, |
|
77 }; |
|
78 |
|
79 /* |
|
80 * This sets up a hierarchy of settings to test. |
|
81 * |
|
82 * The keys are String arrays representing the path through menu items |
|
83 * (the single-item arrays being top-level categories), and each value |
|
84 * is a List of menu items contained within each category. |
|
85 * |
|
86 * Each menu item is itself an array as follows: |
|
87 * - item title |
|
88 * - default string value of item (optional) |
|
89 * - string values of options that are displayed once clicked (optional). |
|
90 */ |
|
91 public void setupSettingsMap(Map<String[], List<String[]>> settingsMap) { |
|
92 settingsMap.put(PATH_CUSTOMIZE, new ArrayList<String[]>(Arrays.asList(OPTIONS_CUSTOMIZE))); |
|
93 settingsMap.put(PATH_HOME, new ArrayList<String[]>(Arrays.asList(OPTIONS_HOME))); |
|
94 settingsMap.put(PATH_DISPLAY, new ArrayList<String[]>(Arrays.asList(OPTIONS_DISPLAY))); |
|
95 settingsMap.put(PATH_PRIVACY, new ArrayList<String[]>(Arrays.asList(OPTIONS_PRIVACY))); |
|
96 settingsMap.put(PATH_MOZILLA, new ArrayList<String[]>(Arrays.asList(OPTIONS_MOZILLA))); |
|
97 } |
|
98 |
|
99 public void testSettingsMenuItems() { |
|
100 blockForGeckoReady(); |
|
101 |
|
102 Map<String[], List<String[]>> settingsMenuItems = new HashMap<String[], List<String[]>>(); |
|
103 setupSettingsMap(settingsMenuItems); |
|
104 |
|
105 // Set special handling for Settings items that are conditionally built. |
|
106 addConditionalSettings(settingsMenuItems); |
|
107 |
|
108 selectMenuItem("Settings"); |
|
109 waitForText("Settings"); |
|
110 |
|
111 // Dismiss the Settings screen and verify that the view is returned to about:home page |
|
112 mActions.sendSpecialKey(Actions.SpecialKey.BACK); |
|
113 |
|
114 // Waiting for page title to appear to be sure that is fully loaded before opening the menu |
|
115 waitForText("Enter Search"); |
|
116 verifyUrl("about:home"); |
|
117 |
|
118 selectMenuItem("Settings"); |
|
119 waitForText("Settings"); |
|
120 |
|
121 checkForSync(mDevice); |
|
122 |
|
123 checkMenuHierarchy(settingsMenuItems); |
|
124 } |
|
125 |
|
126 /** |
|
127 * Check for Sync in settings. |
|
128 * |
|
129 * Sync location is a top level menu item on phones, but is under "Customize" on tablets. |
|
130 * |
|
131 */ |
|
132 public void checkForSync(Device device) { |
|
133 if (device.type.equals("tablet")) { |
|
134 // Select "Customize" from settings. |
|
135 String customizeString = "^Customize$"; |
|
136 waitForEnabledText(customizeString); |
|
137 mSolo.clickOnText(customizeString); |
|
138 } |
|
139 mAsserter.ok(mSolo.waitForText("Sync"), "Waiting for Sync option", "The Sync option is present"); |
|
140 } |
|
141 |
|
142 /** |
|
143 * Check for conditions for building certain settings, and add them to be tested |
|
144 * if they are present. |
|
145 */ |
|
146 public void addConditionalSettings(Map<String[], List<String[]>> settingsMap) { |
|
147 // Preferences dependent on RELEASE_BUILD |
|
148 if (!AppConstants.RELEASE_BUILD) { |
|
149 // Text reflow - only built if *not* release build |
|
150 String[] textReflowUi = { "Text reflow" }; |
|
151 settingsMap.get(PATH_DISPLAY).add(textReflowUi); |
|
152 |
|
153 // Anonymous cell tower/wifi collection - only built if *not* release build |
|
154 String[] networkReportingUi = { "Mozilla Location Service", "Receives Wi-Fi and cellular location data when running in the background and shares it with Mozilla to improve our geolocation service" }; |
|
155 settingsMap.get(PATH_MOZILLA).add(networkReportingUi); |
|
156 |
|
157 String[] learnMoreUi = { "Learn more" }; |
|
158 settingsMap.get(PATH_MOZILLA).add(learnMoreUi); |
|
159 } |
|
160 |
|
161 // Automatic updates |
|
162 if (AppConstants.MOZ_UPDATER) { |
|
163 String[] autoUpdateUi = { "Download updates automatically", "Only over Wi-Fi", "Always", "Only over Wi-Fi", "Never" }; |
|
164 settingsMap.get(PATH_CUSTOMIZE).add(autoUpdateUi); |
|
165 } |
|
166 |
|
167 // Crash reporter |
|
168 if (AppConstants.MOZ_CRASHREPORTER) { |
|
169 String[] crashReporterUi = { "Crash Reporter", BRAND_NAME + " submits crash reports to help Mozilla make your browser more stable and secure" }; |
|
170 settingsMap.get(PATH_MOZILLA).add(crashReporterUi); |
|
171 } |
|
172 |
|
173 // Telemetry |
|
174 if (AppConstants.MOZ_TELEMETRY_REPORTING) { |
|
175 String[] telemetryUi = { "Telemetry", "Shares performance, usage, hardware and customization data about your browser with Mozilla to help us make " + BRAND_NAME + " better" }; |
|
176 settingsMap.get(PATH_MOZILLA).add(telemetryUi); |
|
177 } |
|
178 } |
|
179 |
|
180 public void checkMenuHierarchy(Map<String[], List<String[]>> settingsMap) { |
|
181 // Check the items within each category. |
|
182 String section = null; |
|
183 for (Entry<String[], List<String[]>> e : settingsMap.entrySet()) { |
|
184 final String[] menuPath = e.getKey(); |
|
185 |
|
186 for (String menuItem : menuPath) { |
|
187 section = "^" + menuItem + "$"; |
|
188 |
|
189 waitForEnabledText(section); |
|
190 mSolo.clickOnText(section); |
|
191 } |
|
192 |
|
193 List<String[]> sectionItems = e.getValue(); |
|
194 |
|
195 // Check each item of the section. |
|
196 for (String[] item : sectionItems) { |
|
197 int itemLen = item.length; |
|
198 |
|
199 // Each item must at least have a title. |
|
200 mAsserter.ok(item.length > 0, "Section-item", "Each item must at least have a title"); |
|
201 |
|
202 // Check item title. |
|
203 String itemTitle = "^" + item[0] + "$"; |
|
204 boolean foundText = waitForPreferencesText(itemTitle); |
|
205 |
|
206 mAsserter.ok(foundText, "Waiting for settings item " + itemTitle + " in section " + section, |
|
207 "The " + itemTitle + " option is present in section " + section); |
|
208 // Check item default, if it exists. |
|
209 if (itemLen > 1) { |
|
210 String itemDefault = "^" + item[1] + "$"; |
|
211 foundText = waitForPreferencesText(itemDefault); |
|
212 mAsserter.ok(foundText, "Waiting for settings item default " + itemDefault |
|
213 + " in section " + section, |
|
214 "The " + itemDefault + " default is present in section " + section); |
|
215 } |
|
216 // Check item choices, if they exist. |
|
217 if (itemLen > 2) { |
|
218 waitForEnabledText(itemTitle); |
|
219 mSolo.clickOnText(itemTitle); |
|
220 for (int i = 2; i < itemLen; i++) { |
|
221 String itemChoice = "^" + item[i] + "$"; |
|
222 foundText = waitForPreferencesText(itemChoice); |
|
223 mAsserter.ok(foundText, "Waiting for settings item choice " + itemChoice |
|
224 + " in section " + section, |
|
225 "The " + itemChoice + " choice is present in section " + section); |
|
226 } |
|
227 |
|
228 // Leave submenu after checking. |
|
229 if (waitForText("^Cancel$")) { |
|
230 mSolo.clickOnText("^Cancel$"); |
|
231 } else { |
|
232 // Some submenus aren't dialogs, but are nested screens; exit using "back". |
|
233 mActions.sendSpecialKey(Actions.SpecialKey.BACK); |
|
234 } |
|
235 } |
|
236 } |
|
237 |
|
238 // Navigate back if on a phone. Tablets shouldn't do this because they use headers and fragments. |
|
239 if (mDevice.type.equals("phone")) { |
|
240 int menuDepth = menuPath.length; |
|
241 while (menuDepth > 0) { |
|
242 mActions.sendSpecialKey(Actions.SpecialKey.BACK); |
|
243 menuDepth--; |
|
244 // Sleep so subsequent back actions aren't lost. |
|
245 mSolo.sleep(150); |
|
246 } |
|
247 } |
|
248 } |
|
249 } |
|
250 } |