diff --git a/wlauto/workloads/googleplaybooks/__init__.py b/wlauto/workloads/googleplaybooks/__init__.py index 2f9581e3..31cd65cc 100755 --- a/wlauto/workloads/googleplaybooks/__init__.py +++ b/wlauto/workloads/googleplaybooks/__init__.py @@ -13,18 +13,15 @@ # limitations under the License. # -import os -import re - -from wlauto import AndroidUiAutoBenchmark, Parameter +from wlauto import AndroidUxPerfWorkload, Parameter from wlauto.exceptions import DeviceError -class Googleplaybooks(AndroidUiAutoBenchmark): +class Googleplaybooks(AndroidUxPerfWorkload): name = 'googleplaybooks' package = 'com.google.android.apps.books' - version = '3.8.15' # apk version + min_apk_verson = '3.9.37' activity = 'com.google.android.apps.books.app.BooksActivity' view = [package + '/com.google.android.apps.books.app.HomeActivity', package + '/com.android.vending/com.google.android.finsky.activities.MainActivity', @@ -71,24 +68,12 @@ class Googleplaybooks(AndroidUiAutoBenchmark): The word to search for within a selected book. Note: Accepts single words only. """), - Parameter('markers_enabled', kind=bool, default=True, - description=""" - If ``True``, UX_PERF action markers will be emitted to logcat during - the test run. - """), ] + requires_network = True + def validate(self): super(Googleplaybooks, self).validate() - self.uiauto_params['package'] = self.package - self.uiauto_params['markers_enabled'] = self.markers_enabled self.uiauto_params['book_title'] = self.search_book_title.replace(" ", "_") self.uiauto_params['chapter_page_number'] = self.select_chapter_page_number self.uiauto_params['search_word'] = self.search_word - - def initialize(self, context): - super(Googleplaybooks, self).initialize(context) - - # This workload relies on the internet so check that there is a working internet connection - if not self.device.is_network_connected(): - raise DeviceError('Network is not connected for device {}'.format(self.device.name)) diff --git a/wlauto/workloads/googleplaybooks/com.arm.wlauto.uiauto.googleplaybooks.jar b/wlauto/workloads/googleplaybooks/com.arm.wlauto.uiauto.googleplaybooks.jar index 13a616c1..7091f44f 100644 Binary files a/wlauto/workloads/googleplaybooks/com.arm.wlauto.uiauto.googleplaybooks.jar and b/wlauto/workloads/googleplaybooks/com.arm.wlauto.uiauto.googleplaybooks.jar differ diff --git a/wlauto/workloads/googleplaybooks/uiauto/src/com/arm/wlauto/uiauto/UiAutomation.java b/wlauto/workloads/googleplaybooks/uiauto/src/com/arm/wlauto/uiauto/UiAutomation.java index edba383f..95322456 100755 --- a/wlauto/workloads/googleplaybooks/uiauto/src/com/arm/wlauto/uiauto/UiAutomation.java +++ b/wlauto/workloads/googleplaybooks/uiauto/src/com/arm/wlauto/uiauto/UiAutomation.java @@ -29,14 +29,16 @@ import com.arm.wlauto.uiauto.UxPerfUiAutomation; import java.util.concurrent.TimeUnit; import java.util.LinkedHashMap; import java.util.Iterator; +import android.util.Log; import java.util.Map; import java.util.Map.Entry; public class UiAutomation extends UxPerfUiAutomation { - public static String TAG = "uxperf_googleplaybooks"; + protected Bundle parameters; + protected String packageName; + protected String packageID; - public Bundle parameters; private int viewTimeoutSecs = 10; private long viewTimeout = TimeUnit.SECONDS.toMillis(viewTimeoutSecs); @@ -44,6 +46,8 @@ public class UiAutomation extends UxPerfUiAutomation { this.uiAutoTimeout = TimeUnit.SECONDS.toMillis(8); parameters = getParams(); + packageName = parameters.getString("package"); + packageID = packageName + ":id/"; String bookTitle = parameters.getString("book_title").replace("_", " "); String chapterPageNumber = parameters.getString("chapter_page_number"); @@ -120,7 +124,7 @@ public class UiAutomation extends UxPerfUiAutomation { // pick a random sample book. private void clearFirstRunDialogues() throws Exception { UiObject startButton = - new UiObject(new UiSelector().resourceId("com.google.android.apps.books:id/start_button")); + new UiObject(new UiSelector().resourceId(packageID + "start_button")); // First try and skip the sample book selection if (startButton.exists()) { @@ -128,7 +132,7 @@ public class UiAutomation extends UxPerfUiAutomation { } UiObject endButton = - new UiObject(new UiSelector().resourceId("com.google.android.apps.books:id/end_button")); + new UiObject(new UiSelector().resourceId(packageID + "end_button")); // Click next button if it exists if (endButton.exists()) { @@ -147,7 +151,7 @@ public class UiAutomation extends UxPerfUiAutomation { // Searches for a "free" or "purchased" book title in Google play private void searchForBook(final String bookTitle) throws Exception { UiObject search = - new UiObject(new UiSelector().resourceId("com.google.android.apps.books:id/menu_search")); + new UiObject(new UiSelector().resourceId(packageID + "menu_search")); search.click(); UiObject searchText = new UiObject(new UiSelector().textContains("Search") @@ -168,36 +172,31 @@ public class UiAutomation extends UxPerfUiAutomation { // book that contains a "free" or "purchased" book identifier UiSelector bookSelector = new UiSelector().description(desc).className("android.widget.TextView"); - UiObject freeLabel = + UiObject label = new UiObject(new UiSelector().fromParent(bookSelector) .resourceId("com.android.vending:id/li_label") - .description("Free")); - - UiObject purchasedLabel = - new UiObject(new UiSelector().fromParent(bookSelector) - .resourceId("com.android.vending:id/li_label") - .description("Purchased")); + .descriptionMatches("^(Purchased|Free)$")); UiScrollable searchResultsList = new UiScrollable(new UiSelector().resourceId("com.android.vending:id/search_results_list")); - int maxSwipes = 10; - while (!freeLabel.exists() && !purchasedLabel.exists()) { - if (maxSwipes <= 0) { - throw new UiObjectNotFoundException("Could not find free or purchased book \"" + bookTitle + "\""); + final int maxSearchTime = 30; + int searchTime = maxSearchTime; + + while (!label.exists()) { + if (searchTime <= 0) { + throw new UiObjectNotFoundException( + "Exceeded maximum search time (" + maxSearchTime + " seconds) to find book \"" + bookTitle + "\""); } else { - searchResultsList.swipeUp(10); - maxSwipes--; + uiDeviceSwipeDown(100); + sleep(1); + searchTime--; } } // Click on either the first "free" or "purchased" book found that // matches the book title - try { - freeLabel.click(); - } catch (UiObjectNotFoundException e) { - purchasedLabel.click(); - } + label.click(); } private void addToLibrary() throws Exception { @@ -244,7 +243,7 @@ public class UiAutomation extends UxPerfUiAutomation { private void openBook(final String bookTitle) throws Exception { UiScrollable cardsGrid = - new UiScrollable(new UiSelector().resourceId("com.google.android.apps.books:id/cards_grid")); + new UiScrollable(new UiSelector().resourceId(packageID + "cards_grid")); UiSelector bookSelector = new UiSelector().text(bookTitle).className("android.widget.TextView"); UiObject book = new UiObject(bookSelector); @@ -253,7 +252,7 @@ public class UiAutomation extends UxPerfUiAutomation { // can assume any newly downloaded books will be visible on the first // screen. UiObject menuSort = - getUiObjectByResourceId("com.google.android.apps.books:id/menu_sort", "android.widget.TextView"); + getUiObjectByResourceId(packageID + "menu_sort", "android.widget.TextView"); menuSort.click(); UiObject sortByRecent = getUiObjectByText("Recent", "android.widget.TextView"); @@ -265,16 +264,12 @@ public class UiAutomation extends UxPerfUiAutomation { UiObject downloadComplete = new UiObject(new UiSelector().fromParent(bookSelector).description("100% downloaded")); - int maxDownloadTime = 120; // seconds + long maxWaitTimeSeconds = 120; + long maxWaitTime = TimeUnit.SECONDS.toMillis(maxWaitTimeSeconds); - while (!downloadComplete.exists()) { - if (maxDownloadTime <= 0) { + if (!downloadComplete.waitForExists(maxWaitTime)) { throw new UiObjectNotFoundException( - "Exceeded maximum wait time (" + maxDownloadTime + " seconds) to download book \"" + bookTitle + "\""); - } else { - sleep(1); - maxDownloadTime--; - } + "Exceeded maximum wait time (" + maxWaitTimeSeconds + " seconds) to download book \"" + bookTitle + "\""); } book.click(); @@ -353,11 +348,10 @@ public class UiAutomation extends UxPerfUiAutomation { private void selectChapter(final String chapterPageNumber) throws Exception { getDropdownMenu(); - UiObject contents = getUiObjectByResourceId("com.google.android.apps.books:id/menu_reader_toc", - "android.widget.TextView"); + UiObject contents = getUiObjectByResourceId(packageID + "menu_reader_toc"); contents.clickAndWaitForNewWindow(uiAutoTimeout); - UiObject toChapterView = getUiObjectByResourceId("com.google.android.apps.books:id/toc_list_view", + UiObject toChapterView = getUiObjectByResourceId(packageID + "toc_list_view", "android.widget.ExpandableListView"); // Navigate to top of chapter view @@ -375,18 +369,20 @@ public class UiAutomation extends UxPerfUiAutomation { ActionLogger logger = new ActionLogger(testTag, parameters); logger.start(); + hideDropDownMenu(); + UiObject clickable = new UiObject(new UiSelector().longClickable(true)); uiObjectPerformLongClick(clickable, 100); UiObject addNoteButton = new UiObject( - new UiSelector().resourceId("com.google.android.apps.books:id/add_note_button")); + new UiSelector().resourceId(packageID + "add_note_button")); addNoteButton.click(); - UiObject noteEditText = getUiObjectByResourceId("com.google.android.apps.books:id/note_edit_text", + UiObject noteEditText = getUiObjectByResourceId(packageID + "note_edit_text", "android.widget.EditText"); noteEditText.setText(text); - UiObject noteMenuButton = getUiObjectByResourceId("com.google.android.apps.books:id/note_menu_button", + UiObject noteMenuButton = getUiObjectByResourceId(packageID + "note_menu_button", "android.widget.ImageButton"); noteMenuButton.click(); @@ -407,7 +403,7 @@ public class UiAutomation extends UxPerfUiAutomation { uiObjectPerformLongClick(clickable, 100); UiObject removeButton = new UiObject( - new UiSelector().resourceId("com.google.android.apps.books:id/remove_highlight_button")); + new UiSelector().resourceId(packageID + "remove_highlight_button")); removeButton.click(); UiObject confirmRemove = getUiObjectByText("Remove", "android.widget.Button"); @@ -425,16 +421,16 @@ public class UiAutomation extends UxPerfUiAutomation { getDropdownMenu(); logger.start(); UiObject search = new UiObject( - new UiSelector().resourceId("com.google.android.apps.books:id/menu_search")); + new UiSelector().resourceId(packageID + "menu_search")); search.click(); UiObject searchText = new UiObject( - new UiSelector().resourceId("com.google.android.apps.books:id/search_src_text")); + new UiSelector().resourceId(packageID + "search_src_text")); searchText.setText(text); pressEnter(); UiObject resultList = new UiObject( - new UiSelector().resourceId("com.google.android.apps.books:id/search_results_list")); + new UiSelector().resourceId(packageID + "search_results_list")); // Allow extra time for search queries involing high freqency words final long searchTimeout = TimeUnit.SECONDS.toMillis(20); @@ -459,13 +455,13 @@ public class UiAutomation extends UxPerfUiAutomation { String testTag = "switch_page_style"; getDropdownMenu(); - UiObject readerSettings = getUiObjectByResourceId("com.google.android.apps.books:id/menu_reader_settings", + UiObject readerSettings = getUiObjectByResourceId(packageID + "menu_reader_settings", "android.widget.TextView"); readerSettings.click(); // Check for lighting option button on newer versions UiObject lightingOptionsButton = - new UiObject(new UiSelector().resourceId("com.google.android.apps.books:id/lighting_options_button")); + new UiObject(new UiSelector().resourceId(packageID + "lighting_options_button")); if (lightingOptionsButton.exists()) { lightingOptionsButton.click(); @@ -474,15 +470,22 @@ public class UiAutomation extends UxPerfUiAutomation { String[] styles = {"Night", "Sepia", "Day"}; for (String style : styles) { - ActionLogger logger = new ActionLogger(testTag + "_" + style, parameters); - logger.start(); - UiObject pageStyle = new UiObject(new UiSelector().description(style)); - pageStyle.clickAndWaitForNewWindow(viewTimeout); - logger.stop(); + try { + ActionLogger logger = new ActionLogger(testTag + "_" + style, parameters); + logger.start(); + UiObject pageStyle = new UiObject(new UiSelector().description(style)); + pageStyle.clickAndWaitForNewWindow(viewTimeout); + logger.stop(); + } catch (UiObjectNotFoundException e) { + // On some devices the lighting options menu disappears + // between clicks. Searching for the menu again would affect + // the logger timings so log a message and continue + Log.e("GooglePlayBooks", "Could not find pageStyle \"" + style + "\""); + } } sleep(2); - tapDisplayCentre(); + tapDisplayCentre(); // exit reader settings dialog waitForPage(); } @@ -509,28 +512,37 @@ public class UiAutomation extends UxPerfUiAutomation { // Helper for accessing the drop down menu private void getDropdownMenu() throws Exception { - sleep(1); // Allow previous views to settle - int height = getDisplayHeight(); - int width = getDisplayCentreWidth(); - getUiDevice().swipe(width, 20, width, height / 10, 50); - - // selecting the drop down menu can be unreliable so check for its - // existence and if not present try for a second time using a different - // start point and step size UiObject actionBar = - new UiObject(new UiSelector().resourceId("com.google.android.apps.books:id/action_bar")); + new UiObject(new UiSelector().resourceId(packageID + "action_bar")); - long actionBarTimeout = TimeUnit.SECONDS.toMillis(3); + if (!actionBar.exists()) { + tapDisplayCentre(); + sleep(1); // Allow previous views to settle + } - if (!actionBar.waitForExists(actionBarTimeout)) { - getUiDevice().swipe(width, 5, width, height / 10, 20); + if (!actionBar.exists()) { + throw new UiObjectNotFoundException("Could not find \"action bar\"."); + } + } + + private void hideDropDownMenu() throws Exception { + UiObject actionBar = + new UiObject(new UiSelector().resourceId(packageID + "action_bar")); + + if (actionBar.exists()) { + tapDisplayCentre(); + sleep(1); // Allow previous views to settle + } + + if (actionBar.exists()) { + throw new UiObjectNotFoundException("Could not close \"action bar\"."); } } // Helper for waiting on a page between actions private UiObject waitForPage() throws Exception { UiObject activityReader = - new UiObject(new UiSelector().resourceId("com.google.android.apps.books:id/activity_reader") + new UiObject(new UiSelector().resourceId(packageID + "activity_reader") .childSelector(new UiSelector().focusable(true))); // On some devices the object in the view hierarchy is found before it