|
1 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
4 |
|
5 package org.mozilla.gecko.tests.components; |
|
6 |
|
7 import static org.mozilla.gecko.tests.helpers.AssertionHelper.fAssertEquals; |
|
8 import static org.mozilla.gecko.tests.helpers.AssertionHelper.fAssertFalse; |
|
9 import static org.mozilla.gecko.tests.helpers.AssertionHelper.fAssertTrue; |
|
10 |
|
11 import java.util.List; |
|
12 |
|
13 import org.mozilla.gecko.R; |
|
14 import org.mozilla.gecko.menu.MenuItemActionBar; |
|
15 import org.mozilla.gecko.menu.MenuItemDefault; |
|
16 import org.mozilla.gecko.tests.UITestContext; |
|
17 import org.mozilla.gecko.tests.helpers.WaitHelper; |
|
18 import org.mozilla.gecko.util.HardwareUtils; |
|
19 |
|
20 import android.view.View; |
|
21 |
|
22 import com.jayway.android.robotium.solo.Condition; |
|
23 import com.jayway.android.robotium.solo.RobotiumUtils; |
|
24 import com.jayway.android.robotium.solo.Solo; |
|
25 |
|
26 /** |
|
27 * A class representing any interactions that take place on the app menu. |
|
28 */ |
|
29 public class AppMenuComponent extends BaseComponent { |
|
30 public enum MenuItem { |
|
31 FORWARD(R.string.forward), |
|
32 NEW_TAB(R.string.new_tab); |
|
33 |
|
34 private final int resourceID; |
|
35 private String stringResource; |
|
36 |
|
37 MenuItem(final int resourceID) { |
|
38 this.resourceID = resourceID; |
|
39 } |
|
40 |
|
41 public String getString(final Solo solo) { |
|
42 if (stringResource == null) { |
|
43 stringResource = solo.getString(resourceID); |
|
44 } |
|
45 |
|
46 return stringResource; |
|
47 } |
|
48 }; |
|
49 |
|
50 public AppMenuComponent(final UITestContext testContext) { |
|
51 super(testContext); |
|
52 } |
|
53 |
|
54 private void assertMenuIsNotOpen() { |
|
55 fAssertFalse("Menu is not open", isMenuOpen()); |
|
56 } |
|
57 |
|
58 private View getOverflowMenuButtonView() { |
|
59 return mSolo.getView(R.id.menu); |
|
60 } |
|
61 |
|
62 /** |
|
63 * Try to find a MenuItemActionBar/MenuItemDefault with the given text set as contentDescription / text. |
|
64 * |
|
65 * Will return null when the Android legacy menu is in use. |
|
66 * |
|
67 * This method is dependent on not having two views with equivalent contentDescription / text. |
|
68 */ |
|
69 private View findAppMenuItemView(String text) { |
|
70 final List<View> views = mSolo.getViews(); |
|
71 |
|
72 final List<MenuItemActionBar> menuItemActionBarList = RobotiumUtils.filterViews(MenuItemActionBar.class, views); |
|
73 for (MenuItemActionBar menuItem : menuItemActionBarList) { |
|
74 if (menuItem.getContentDescription().equals(text)) { |
|
75 return menuItem; |
|
76 } |
|
77 } |
|
78 |
|
79 final List<MenuItemDefault> menuItemDefaultList = RobotiumUtils.filterViews(MenuItemDefault.class, views); |
|
80 for (MenuItemDefault menuItem : menuItemDefaultList) { |
|
81 if (menuItem.getText().equals(text)) { |
|
82 return menuItem; |
|
83 } |
|
84 } |
|
85 |
|
86 return null; |
|
87 } |
|
88 |
|
89 public void pressMenuItem(MenuItem menuItem) { |
|
90 openAppMenu(); |
|
91 |
|
92 final String text = menuItem.getString(mSolo); |
|
93 final View menuItemView = findAppMenuItemView(text); |
|
94 |
|
95 if (menuItemView != null) { |
|
96 fAssertTrue("The menu item is enabled", menuItemView.isEnabled()); |
|
97 fAssertEquals("The menu item is visible", View.VISIBLE, menuItemView.getVisibility()); |
|
98 |
|
99 mSolo.clickOnView(menuItemView); |
|
100 } else { |
|
101 // We could not find a view representing this menu item: Let's let Robotium try to |
|
102 // locate and click it in the legacy Android menu (devices with Android 2.x). |
|
103 // |
|
104 // Even though we already opened the menu to see if we can locate the menu item, |
|
105 // Robotium will also try to open the menu if it doesn't find an open dialog (Does |
|
106 // not happen in this case). |
|
107 mSolo.clickOnMenuItem(text, true); |
|
108 } |
|
109 } |
|
110 |
|
111 private void openAppMenu() { |
|
112 assertMenuIsNotOpen(); |
|
113 |
|
114 if (HardwareUtils.hasMenuButton()) { |
|
115 mSolo.sendKey(Solo.MENU); |
|
116 } else { |
|
117 pressOverflowMenuButton(); |
|
118 } |
|
119 |
|
120 waitForMenuOpen(); |
|
121 } |
|
122 |
|
123 private void pressOverflowMenuButton() { |
|
124 final View overflowMenuButton = getOverflowMenuButtonView(); |
|
125 |
|
126 fAssertTrue("The overflow menu button is enabled", overflowMenuButton.isEnabled()); |
|
127 fAssertEquals("The overflow menu button is visible", View.VISIBLE, overflowMenuButton.getVisibility()); |
|
128 |
|
129 mSolo.clickOnView(overflowMenuButton, true); |
|
130 } |
|
131 |
|
132 private boolean isMenuOpen() { |
|
133 // The presence of the "New tab" menu item is our best guess about whether |
|
134 // the menu is open or not. |
|
135 return mSolo.searchText(MenuItem.NEW_TAB.getString(mSolo)); |
|
136 } |
|
137 |
|
138 private void waitForMenuOpen() { |
|
139 WaitHelper.waitFor("menu to open", new Condition() { |
|
140 @Override |
|
141 public boolean isSatisfied() { |
|
142 return isMenuOpen(); |
|
143 } |
|
144 }); |
|
145 } |
|
146 } |