Bug 996227 - Add "Save as PDF" button test. r=mcomella
authorvivek <vivekb.balakrishnan>
Mon, 28 Jul 2014 11:54:00 +0200
changeset 197031 71ef1c18665f4c2b1d40fae19efee5c7994ff9ae
parent 197030 f4ac52fb6c84da1709ee94757f7773ebfbe442c8
child 197032 20c0341fb3acadeb98bc9dd41a8b918c7f424ad7
push id47022
push usercbook@mozilla.com
push dateThu, 31 Jul 2014 11:07:00 +0000
treeherdermozilla-inbound@597be00ffc53 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmcomella
bugs996227
milestone34.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 996227 - Add "Save as PDF" button test. r=mcomella
mobile/android/base/tests/components/AppMenuComponent.java
mobile/android/base/tests/robocop.ini
mobile/android/base/tests/testAppMenuPathways.java
--- a/mobile/android/base/tests/components/AppMenuComponent.java
+++ b/mobile/android/base/tests/components/AppMenuComponent.java
@@ -9,32 +9,36 @@ import static org.mozilla.gecko.tests.he
 import static org.mozilla.gecko.tests.helpers.AssertionHelper.fAssertTrue;
 
 import java.util.List;
 
 import org.mozilla.gecko.R;
 import org.mozilla.gecko.menu.MenuItemActionBar;
 import org.mozilla.gecko.menu.MenuItemDefault;
 import org.mozilla.gecko.tests.UITestContext;
+import org.mozilla.gecko.tests.helpers.DeviceHelper;
 import org.mozilla.gecko.tests.helpers.WaitHelper;
 import org.mozilla.gecko.util.HardwareUtils;
 
 import android.view.View;
 
 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 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;
         }
@@ -43,24 +47,93 @@ public class AppMenuComponent extends Ba
             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));
+                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 don't have parent menu item "page", check for menu item represented by pageMenuItem.
+            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 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.
      *
      * Will return null when the Android legacy menu is in use.
@@ -82,42 +155,71 @@ public class AppMenuComponent extends Ba
             if (menuItem.getText().equals(text)) {
                 return menuItem;
             }
         }
 
         return null;
     }
 
-    public void pressMenuItem(MenuItem menuItem) {
-        openAppMenu();
+    /**
+     * 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);
+    }
 
-        final String text = menuItem.getString(mSolo);
-        final View menuItemView = findAppMenuItemView(text);
+    private void pressMenuItem(final String menuItemTitle) {
+        fAssertTrue("Menu is open", isMenuOpen(menuItemTitle));
 
-        if (menuItemView != null) {
-            fAssertTrue("The menu item is enabled", menuItemView.isEnabled());
-            fAssertEquals("The menu item is visible", View.VISIBLE, menuItemView.getVisibility());
+        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 {
-            // We could not find a view representing this menu item: Let's let Robotium try to
-            // locate and click it in the legacy Android menu (devices with Android 2.x).
-            //
-            // Even though we already opened the menu to see if we can locate the menu item,
-            // Robotium will also try to open the menu if it doesn't find an open dialog (Does
-            // not happen in this case).
-            mSolo.clickOnMenuItem(text, true);
+            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();
 
-        if (HardwareUtils.hasMenuButton()) {
+        // 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();
     }
 
@@ -125,20 +227,34 @@ public class AppMenuComponent extends Ba
         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() {
-        // The presence of the "New tab" menu item is our best guess about whether
-        // the menu is open or not.
-        return mSolo.searchText(MenuItem.NEW_TAB.getString(mSolo));
+        return isMenuOpen(MenuItem.NEW_TAB.getString(mSolo));
+    }
+
+    /**
+     * 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);
     }
 
     private void waitForMenuOpen() {
         WaitHelper.waitFor("menu to open", new Condition() {
             @Override
             public boolean isSatisfied() {
                 return isMenuOpen();
             }
--- a/mobile/android/base/tests/robocop.ini
+++ b/mobile/android/base/tests/robocop.ini
@@ -117,16 +117,17 @@ skip-if = android_version == "10"
 #[testCheck2]
 #[testBrowserProviderPerf]
 
 # Using UITest
 #[testAboutHomePageNavigation] # see bug 947550, bug 979038 and bug 977952
 [testAboutHomeVisibility]
 # disabled on Android 2.3; bug 946656
 skip-if = android_version == "10"
+[testAppMenuPathways]
 [testEventDispatcher]
 [testInputConnection]
 # disabled on Android 2.3; bug 1025968
 skip-if = android_version == "10"
 [testJavascriptBridge]
 [testNativeCrypto]
 [testSessionHistory]
 
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/tests/testAppMenuPathways.java
@@ -0,0 +1,34 @@
+package org.mozilla.gecko.tests;
+
+import org.mozilla.gecko.tests.components.AppMenuComponent;
+import org.mozilla.gecko.tests.helpers.GeckoHelper;
+import org.mozilla.gecko.tests.helpers.NavigationHelper;
+
+/**
+ * Set of tests to test UI App menu and submenus the user interact with.
+ */
+public class testAppMenuPathways extends UITest {
+
+    /**
+     * Robocop supports only a single test function per test class. Therefore, we
+     * have a single top-level test function that dispatches to sub-tests.
+     */
+    public void testAppMenuPathways() {
+        GeckoHelper.blockForReady();
+
+        _testSaveAsPDFPathway();
+    }
+
+    public void _testSaveAsPDFPathway() {
+        // Page menu should be disabled in about:home.
+        mAppMenu.assertMenuItemIsDisabledAndVisible(AppMenuComponent.PageMenuItem.SAVE_AS_PDF);
+
+        // Navigate to a page to test save as pdf functionality.
+        NavigationHelper.enterAndLoadUrl(StringHelper.ROBOCOP_BLANK_PAGE_01_URL);
+        mToolbar.assertTitle(StringHelper.ROBOCOP_BLANK_PAGE_01_TITLE);
+
+        // Test save as pdf functionality.
+        // The following call doesn't wait for the resulting pdf but checks that no exception are thrown.
+        mAppMenu.pressMenuItem(AppMenuComponent.PageMenuItem.SAVE_AS_PDF);
+    }
+}
\ No newline at end of file