mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-06-02 17:41:47 +00:00
319 lines
12 KiB
Java
319 lines
12 KiB
Java
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
package org.mozilla.goanna.tests.components;
|
|
|
|
import static org.mozilla.goanna.tests.helpers.AssertionHelper.fAssertEquals;
|
|
import static org.mozilla.goanna.tests.helpers.AssertionHelper.fAssertFalse;
|
|
import static org.mozilla.goanna.tests.helpers.AssertionHelper.fAssertNotNull;
|
|
import static org.mozilla.goanna.tests.helpers.AssertionHelper.fAssertTrue;
|
|
|
|
import java.util.List;
|
|
|
|
import org.mozilla.goanna.R;
|
|
import org.mozilla.goanna.menu.MenuItemActionBar;
|
|
import org.mozilla.goanna.menu.MenuItemDefault;
|
|
import org.mozilla.goanna.tests.UITestContext;
|
|
import org.mozilla.goanna.tests.helpers.DeviceHelper;
|
|
import org.mozilla.goanna.tests.helpers.WaitHelper;
|
|
import org.mozilla.goanna.util.HardwareUtils;
|
|
|
|
import android.text.TextUtils;
|
|
import android.view.View;
|
|
import android.widget.TextView;
|
|
|
|
import com.jayway.android.robotium.solo.Condition;
|
|
import com.jayway.android.robotium.solo.RobotiumUtils;
|
|
import com.jayway.android.robotium.solo.Solo;
|
|
|
|
/**
|
|
* A class representing any interactions that take place on the app menu.
|
|
*/
|
|
public class AppMenuComponent extends BaseComponent {
|
|
private static final long MAX_WAITTIME_FOR_MENU_UPDATE_IN_MS = 1000L;
|
|
|
|
private Boolean hasLegacyMenu = null;
|
|
|
|
public enum MenuItem {
|
|
FORWARD(R.string.forward),
|
|
NEW_TAB(R.string.new_tab),
|
|
PAGE(R.string.page),
|
|
RELOAD(R.string.reload);
|
|
|
|
private final int resourceID;
|
|
private String stringResource;
|
|
|
|
MenuItem(final int resourceID) {
|
|
this.resourceID = resourceID;
|
|
}
|
|
|
|
public String getString(final Solo solo) {
|
|
if (stringResource == null) {
|
|
stringResource = solo.getString(resourceID);
|
|
}
|
|
|
|
return stringResource;
|
|
}
|
|
};
|
|
|
|
public enum PageMenuItem {
|
|
SAVE_AS_PDF(R.string.save_as_pdf);
|
|
|
|
private static final MenuItem PARENT_MENU = MenuItem.PAGE;
|
|
|
|
private final int resourceID;
|
|
private String stringResource;
|
|
|
|
PageMenuItem(final int resourceID) {
|
|
this.resourceID = resourceID;
|
|
}
|
|
|
|
public String getString(final Solo solo) {
|
|
if (stringResource == null) {
|
|
stringResource = solo.getString(resourceID);
|
|
}
|
|
|
|
return stringResource;
|
|
}
|
|
};
|
|
|
|
public AppMenuComponent(final UITestContext testContext) {
|
|
super(testContext);
|
|
}
|
|
|
|
private void assertMenuIsNotOpen() {
|
|
fAssertFalse("Menu is not open", isMenuOpen());
|
|
}
|
|
|
|
/**
|
|
* Legacy Android devices doesn't have hierarchical menus. Sub-menus, such as "Page", are missing in these devices.
|
|
* Try to determine if the menu item "Page" is present.
|
|
*
|
|
* TODO : This fragile way to determine legacy menus should be replaced with a check for 6-panel menu item.
|
|
*
|
|
* @return true if there is a legacy menu.
|
|
*/
|
|
private boolean hasLegacyMenu() {
|
|
if (hasLegacyMenu == null) {
|
|
hasLegacyMenu = findAppMenuItemView(MenuItem.PAGE.getString(mSolo)) == null;
|
|
}
|
|
|
|
return hasLegacyMenu;
|
|
}
|
|
|
|
public void assertMenuItemIsDisabledAndVisible(PageMenuItem pageMenuItem) {
|
|
openAppMenu();
|
|
|
|
if (!hasLegacyMenu()) {
|
|
// Non-legacy devices have hierarchical menu, check for parent menu item "page".
|
|
final View parentMenuItemView = findAppMenuItemView(MenuItem.PAGE.getString(mSolo));
|
|
if (parentMenuItemView.isEnabled()) {
|
|
fAssertTrue("The parent 'page' menu item is enabled", parentMenuItemView.isEnabled());
|
|
fAssertEquals("The parent 'page' menu item is visible", View.VISIBLE,
|
|
parentMenuItemView.getVisibility());
|
|
|
|
// Parent menu "page" is enabled, open page menu and check for menu item represented by pageMenuItem.
|
|
pressMenuItem(MenuItem.PAGE.getString(mSolo));
|
|
|
|
final View pageMenuItemView = findAppMenuItemView(pageMenuItem.getString(mSolo));
|
|
fAssertNotNull("The page menu item is not null", pageMenuItemView);
|
|
fAssertFalse("The page menu item is not enabled", pageMenuItemView.isEnabled());
|
|
fAssertEquals("The page menu item is visible", View.VISIBLE, pageMenuItemView.getVisibility());
|
|
} else {
|
|
fAssertFalse("The parent 'page' menu item is not enabled", parentMenuItemView.isEnabled());
|
|
fAssertEquals("The parent 'page' menu item is visible", View.VISIBLE, parentMenuItemView.getVisibility());
|
|
}
|
|
} else {
|
|
// Legacy devices (Android 2.3 and earlier) don't have the parent menu, "Page", so check directly for the menu
|
|
// item represented by pageMenuItem.
|
|
//
|
|
// We need to make sure the appropriate menu view is constructed
|
|
// so open the "More" menu to additionally construct those views.
|
|
openLegacyMoreMenu();
|
|
|
|
final View pageMenuItemView = findAppMenuItemView(pageMenuItem.getString(mSolo));
|
|
fAssertFalse("The page menu item is not enabled", pageMenuItemView.isEnabled());
|
|
fAssertEquals("The page menu item is visible", View.VISIBLE, pageMenuItemView.getVisibility());
|
|
|
|
// Close the "More" menu.
|
|
mSolo.goBack();
|
|
}
|
|
|
|
// Close the App Menu.
|
|
mSolo.goBack();
|
|
}
|
|
|
|
private View getOverflowMenuButtonView() {
|
|
return mSolo.getView(R.id.menu);
|
|
}
|
|
|
|
/**
|
|
* Try to find a MenuItemActionBar/MenuItemDefault with the given text set as contentDescription / text.
|
|
*
|
|
* When using legacy menus, make sure the menu has been opened to the appropriate level
|
|
* (i.e. base menu or "More" menu) to ensure the appropriate menu views are in memory.
|
|
* TODO: ^ Maybe we just need to have opened the "More" menu and the current one doesn't matter.
|
|
*
|
|
* This method is dependent on not having two views with equivalent contentDescription / text.
|
|
*/
|
|
private View findAppMenuItemView(String text) {
|
|
mSolo.waitForText(text, 1, MAX_WAITTIME_FOR_MENU_UPDATE_IN_MS);
|
|
|
|
final List<View> views = mSolo.getViews();
|
|
|
|
final List<MenuItemActionBar> menuItemActionBarList = RobotiumUtils.filterViews(MenuItemActionBar.class, views);
|
|
for (MenuItemActionBar menuItem : menuItemActionBarList) {
|
|
if (TextUtils.equals(menuItem.getContentDescription(), text)) {
|
|
return menuItem;
|
|
}
|
|
}
|
|
|
|
final List<MenuItemDefault> menuItemDefaultList = RobotiumUtils.filterViews(MenuItemDefault.class, views);
|
|
for (MenuItemDefault menuItem : menuItemDefaultList) {
|
|
if (TextUtils.equals(menuItem.getText(), text)) {
|
|
return menuItem;
|
|
}
|
|
}
|
|
|
|
// On Android 2.3, menu items may be instances of
|
|
// com.android.internal.view.menu.ListMenuItemView, each with a child
|
|
// android.widget.RelativeLayout which in turn has a child
|
|
// TextView with the appropriate text.
|
|
final List<TextView> textViewList = RobotiumUtils.filterViews(TextView.class, views);
|
|
for (TextView textView : textViewList) {
|
|
if (TextUtils.equals(textView.getText(), text)) {
|
|
View relativeLayout = (View) textView.getParent();
|
|
View listMenuItemView = (View)relativeLayout.getParent();
|
|
return listMenuItemView;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Helper function to let Robotium locate and click menu item from legacy Android menu (devices with Android 2.x).
|
|
*
|
|
* Robotium will also try to open the menu if there are no open dialog.
|
|
*
|
|
* @param menuItemText, The title of menu item to open.
|
|
*/
|
|
private void pressLegacyMenuItem(final String menuItemTitle) {
|
|
mSolo.clickOnMenuItem(menuItemTitle, true);
|
|
}
|
|
|
|
private void pressMenuItem(final String menuItemTitle) {
|
|
fAssertTrue("Menu is open", isMenuOpen(menuItemTitle));
|
|
|
|
if (!hasLegacyMenu()) {
|
|
final View menuItemView = findAppMenuItemView(menuItemTitle);
|
|
|
|
fAssertTrue(String.format("The menu item %s is enabled", menuItemTitle), menuItemView.isEnabled());
|
|
fAssertEquals(String.format("The menu item %s is visible", menuItemTitle), View.VISIBLE,
|
|
menuItemView.getVisibility());
|
|
|
|
mSolo.clickOnView(menuItemView);
|
|
} else {
|
|
pressLegacyMenuItem(menuItemTitle);
|
|
}
|
|
}
|
|
|
|
private void pressSubMenuItem(final String parentMenuItemTitle, final String childMenuItemTitle) {
|
|
openAppMenu();
|
|
|
|
if (!hasLegacyMenu()) {
|
|
pressMenuItem(parentMenuItemTitle);
|
|
|
|
// Child menu item is not pressed yet, Click on it.
|
|
pressMenuItem(childMenuItemTitle);
|
|
} else {
|
|
pressLegacyMenuItem(childMenuItemTitle);
|
|
}
|
|
}
|
|
|
|
public void pressMenuItem(MenuItem menuItem) {
|
|
openAppMenu();
|
|
pressMenuItem(menuItem.getString(mSolo));
|
|
}
|
|
|
|
public void pressMenuItem(final PageMenuItem pageMenuItem) {
|
|
pressSubMenuItem(PageMenuItem.PARENT_MENU.getString(mSolo), pageMenuItem.getString(mSolo));
|
|
}
|
|
|
|
private void openAppMenu() {
|
|
assertMenuIsNotOpen();
|
|
|
|
// This is a hack needed for tablets where the OverflowMenuButton is always in the GONE state,
|
|
// so we press the menu key instead.
|
|
if (HardwareUtils.hasMenuButton() || DeviceHelper.isTablet()) {
|
|
mSolo.sendKey(Solo.MENU);
|
|
} else {
|
|
pressOverflowMenuButton();
|
|
}
|
|
|
|
waitForMenuOpen();
|
|
}
|
|
|
|
/**
|
|
* Opens the "More" options menu on legacy Android devices. Assumes the base menu
|
|
* (i.e. {@link #openAppMenu()}) has already been called and thus the menu is open.
|
|
*/
|
|
private void openLegacyMoreMenu() {
|
|
fAssertTrue("The base menu is already open", isMenuOpen());
|
|
|
|
// Since there may be more views with "More" on the screen,
|
|
// this is not robust. However, there may not be a better way.
|
|
mSolo.clickOnText("^More$");
|
|
|
|
WaitHelper.waitFor("legacy \"More\" menu to open", new Condition() {
|
|
@Override
|
|
public boolean isSatisfied() {
|
|
return isLegacyMoreMenuOpen();
|
|
}
|
|
});
|
|
}
|
|
|
|
private void pressOverflowMenuButton() {
|
|
final View overflowMenuButton = getOverflowMenuButtonView();
|
|
|
|
fAssertTrue("The overflow menu button is enabled", overflowMenuButton.isEnabled());
|
|
fAssertEquals("The overflow menu button is visible", View.VISIBLE, overflowMenuButton.getVisibility());
|
|
|
|
mSolo.clickOnView(overflowMenuButton, true);
|
|
}
|
|
|
|
/**
|
|
* Determines whether the app menu is open by searching for the text "New tab".
|
|
*
|
|
* @return true if app menu is open.
|
|
*/
|
|
private boolean isMenuOpen() {
|
|
return isMenuOpen(MenuItem.NEW_TAB.getString(mSolo));
|
|
}
|
|
|
|
private boolean isLegacyMoreMenuOpen() {
|
|
// Check if the first menu option is visible.
|
|
return mSolo.searchText(mSolo.getString(R.string.share), true);
|
|
}
|
|
|
|
/**
|
|
* Determines whether the app menu is open by searching for the text in menuItemTitle.
|
|
*
|
|
* @param menuItemTitle, The contentDescription of menu item to search.
|
|
*
|
|
* @return true if app menu is open.
|
|
*/
|
|
private boolean isMenuOpen(String menuItemTitle) {
|
|
return mSolo.searchText(menuItemTitle, true);
|
|
}
|
|
|
|
private void waitForMenuOpen() {
|
|
WaitHelper.waitFor("menu to open", new Condition() {
|
|
@Override
|
|
public boolean isSatisfied() {
|
|
return isMenuOpen();
|
|
}
|
|
});
|
|
}
|
|
}
|