1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/mobile/android/base/tests/components/AppMenuComponent.java Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,146 @@ 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.components; 1.9 + 1.10 +import static org.mozilla.gecko.tests.helpers.AssertionHelper.fAssertEquals; 1.11 +import static org.mozilla.gecko.tests.helpers.AssertionHelper.fAssertFalse; 1.12 +import static org.mozilla.gecko.tests.helpers.AssertionHelper.fAssertTrue; 1.13 + 1.14 +import java.util.List; 1.15 + 1.16 +import org.mozilla.gecko.R; 1.17 +import org.mozilla.gecko.menu.MenuItemActionBar; 1.18 +import org.mozilla.gecko.menu.MenuItemDefault; 1.19 +import org.mozilla.gecko.tests.UITestContext; 1.20 +import org.mozilla.gecko.tests.helpers.WaitHelper; 1.21 +import org.mozilla.gecko.util.HardwareUtils; 1.22 + 1.23 +import android.view.View; 1.24 + 1.25 +import com.jayway.android.robotium.solo.Condition; 1.26 +import com.jayway.android.robotium.solo.RobotiumUtils; 1.27 +import com.jayway.android.robotium.solo.Solo; 1.28 + 1.29 +/** 1.30 + * A class representing any interactions that take place on the app menu. 1.31 + */ 1.32 +public class AppMenuComponent extends BaseComponent { 1.33 + public enum MenuItem { 1.34 + FORWARD(R.string.forward), 1.35 + NEW_TAB(R.string.new_tab); 1.36 + 1.37 + private final int resourceID; 1.38 + private String stringResource; 1.39 + 1.40 + MenuItem(final int resourceID) { 1.41 + this.resourceID = resourceID; 1.42 + } 1.43 + 1.44 + public String getString(final Solo solo) { 1.45 + if (stringResource == null) { 1.46 + stringResource = solo.getString(resourceID); 1.47 + } 1.48 + 1.49 + return stringResource; 1.50 + } 1.51 + }; 1.52 + 1.53 + public AppMenuComponent(final UITestContext testContext) { 1.54 + super(testContext); 1.55 + } 1.56 + 1.57 + private void assertMenuIsNotOpen() { 1.58 + fAssertFalse("Menu is not open", isMenuOpen()); 1.59 + } 1.60 + 1.61 + private View getOverflowMenuButtonView() { 1.62 + return mSolo.getView(R.id.menu); 1.63 + } 1.64 + 1.65 + /** 1.66 + * Try to find a MenuItemActionBar/MenuItemDefault with the given text set as contentDescription / text. 1.67 + * 1.68 + * Will return null when the Android legacy menu is in use. 1.69 + * 1.70 + * This method is dependent on not having two views with equivalent contentDescription / text. 1.71 + */ 1.72 + private View findAppMenuItemView(String text) { 1.73 + final List<View> views = mSolo.getViews(); 1.74 + 1.75 + final List<MenuItemActionBar> menuItemActionBarList = RobotiumUtils.filterViews(MenuItemActionBar.class, views); 1.76 + for (MenuItemActionBar menuItem : menuItemActionBarList) { 1.77 + if (menuItem.getContentDescription().equals(text)) { 1.78 + return menuItem; 1.79 + } 1.80 + } 1.81 + 1.82 + final List<MenuItemDefault> menuItemDefaultList = RobotiumUtils.filterViews(MenuItemDefault.class, views); 1.83 + for (MenuItemDefault menuItem : menuItemDefaultList) { 1.84 + if (menuItem.getText().equals(text)) { 1.85 + return menuItem; 1.86 + } 1.87 + } 1.88 + 1.89 + return null; 1.90 + } 1.91 + 1.92 + public void pressMenuItem(MenuItem menuItem) { 1.93 + openAppMenu(); 1.94 + 1.95 + final String text = menuItem.getString(mSolo); 1.96 + final View menuItemView = findAppMenuItemView(text); 1.97 + 1.98 + if (menuItemView != null) { 1.99 + fAssertTrue("The menu item is enabled", menuItemView.isEnabled()); 1.100 + fAssertEquals("The menu item is visible", View.VISIBLE, menuItemView.getVisibility()); 1.101 + 1.102 + mSolo.clickOnView(menuItemView); 1.103 + } else { 1.104 + // We could not find a view representing this menu item: Let's let Robotium try to 1.105 + // locate and click it in the legacy Android menu (devices with Android 2.x). 1.106 + // 1.107 + // Even though we already opened the menu to see if we can locate the menu item, 1.108 + // Robotium will also try to open the menu if it doesn't find an open dialog (Does 1.109 + // not happen in this case). 1.110 + mSolo.clickOnMenuItem(text, true); 1.111 + } 1.112 + } 1.113 + 1.114 + private void openAppMenu() { 1.115 + assertMenuIsNotOpen(); 1.116 + 1.117 + if (HardwareUtils.hasMenuButton()) { 1.118 + mSolo.sendKey(Solo.MENU); 1.119 + } else { 1.120 + pressOverflowMenuButton(); 1.121 + } 1.122 + 1.123 + waitForMenuOpen(); 1.124 + } 1.125 + 1.126 + private void pressOverflowMenuButton() { 1.127 + final View overflowMenuButton = getOverflowMenuButtonView(); 1.128 + 1.129 + fAssertTrue("The overflow menu button is enabled", overflowMenuButton.isEnabled()); 1.130 + fAssertEquals("The overflow menu button is visible", View.VISIBLE, overflowMenuButton.getVisibility()); 1.131 + 1.132 + mSolo.clickOnView(overflowMenuButton, true); 1.133 + } 1.134 + 1.135 + private boolean isMenuOpen() { 1.136 + // The presence of the "New tab" menu item is our best guess about whether 1.137 + // the menu is open or not. 1.138 + return mSolo.searchText(MenuItem.NEW_TAB.getString(mSolo)); 1.139 + } 1.140 + 1.141 + private void waitForMenuOpen() { 1.142 + WaitHelper.waitFor("menu to open", new Condition() { 1.143 + @Override 1.144 + public boolean isSatisfied() { 1.145 + return isMenuOpen(); 1.146 + } 1.147 + }); 1.148 + } 1.149 +}