mirror of
https://github.com/ARM-software/workload-automation.git
synced 2025-02-21 20:38:57 +00:00
Merge pull request #263 from jimboatarm/books-codetidy
GooglePlayBooks: Code tidy to conform.
This commit is contained in:
commit
27df426c0d
@ -14,7 +14,6 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
from wlauto import AndroidUxPerfWorkload, Parameter
|
from wlauto import AndroidUxPerfWorkload, Parameter
|
||||||
from wlauto.exceptions import DeviceError
|
|
||||||
|
|
||||||
|
|
||||||
class Googleplaybooks(AndroidUxPerfWorkload):
|
class Googleplaybooks(AndroidUxPerfWorkload):
|
||||||
@ -27,7 +26,7 @@ class Googleplaybooks(AndroidUxPerfWorkload):
|
|||||||
package + '/com.android.vending/com.google.android.finsky.activities.MainActivity',
|
package + '/com.android.vending/com.google.android.finsky.activities.MainActivity',
|
||||||
package + '/com.google.android.apps.books.app.ReadingActivity',
|
package + '/com.google.android.apps.books.app.ReadingActivity',
|
||||||
package + '/com.google.android.apps.books.app.TableOfContentsActivityLight']
|
package + '/com.google.android.apps.books.app.TableOfContentsActivityLight']
|
||||||
description = """
|
description = '''
|
||||||
A workload to perform standard productivity tasks with googleplaybooks.
|
A workload to perform standard productivity tasks with googleplaybooks.
|
||||||
This workload performs various tasks, such as searching for a book title
|
This workload performs various tasks, such as searching for a book title
|
||||||
online, browsing through a book, adding and removing notes, word searching,
|
online, browsing through a book, adding and removing notes, word searching,
|
||||||
@ -48,32 +47,57 @@ class Googleplaybooks(AndroidUxPerfWorkload):
|
|||||||
12. Switches page styles from 'Day' to 'Night' to 'Sepia' and back to 'Day'
|
12. Switches page styles from 'Day' to 'Night' to 'Sepia' and back to 'Day'
|
||||||
13. Uses the 'About this book' facility on the currently selected book
|
13. Uses the 'About this book' facility on the currently selected book
|
||||||
|
|
||||||
NOTE: This workload requires a network connection (ideally, wifi) to run
|
NOTE: This workload requires a network connection (ideally, wifi) to run,
|
||||||
and a Google account to be setup on the device.
|
a Google account to be setup on the device, and payment details for the account.
|
||||||
"""
|
Free books require payment details to have been setup otherwise it fails.
|
||||||
|
Tip: Install the 'Google Opinion Rewards' app to bypass the need to enter valid
|
||||||
|
card/bank detail.
|
||||||
|
'''
|
||||||
|
|
||||||
parameters = [
|
parameters = [
|
||||||
Parameter('search_book_title', kind=str, mandatory=False, default="Hamlet",
|
Parameter('search_book_title', kind=str, default='Nikola Tesla: Imagination and the Man That Invented the 20th Century',
|
||||||
description="""
|
description="""
|
||||||
The book title to search for within Google Play Books archive.
|
The book title to search for within Google Play Books archive.
|
||||||
The book must either be already in the account's library, or free to purchase.
|
The book must either be already in the account's library, or free to purchase.
|
||||||
"""),
|
"""),
|
||||||
Parameter('select_chapter_page_number', kind=int, mandatory=False, default=22,
|
Parameter('library_book_title', kind=str, default='Nikola Tesla',
|
||||||
|
description="""
|
||||||
|
The book title to search for within My Library.
|
||||||
|
The Library name can differ (usually shorter) to the Store name.
|
||||||
|
If left blank, the ``search_book_title`` will be used.
|
||||||
|
"""),
|
||||||
|
Parameter('select_chapter_page_number', kind=int, default=4,
|
||||||
description="""
|
description="""
|
||||||
The Page Number to search for within a selected book's Chapter list.
|
The Page Number to search for within a selected book's Chapter list.
|
||||||
Note: Accepts integers only.
|
Note: Accepts integers only.
|
||||||
"""),
|
"""),
|
||||||
Parameter('search_word', kind=str, mandatory=False, default='the',
|
Parameter('search_word', kind=str, default='the',
|
||||||
description="""
|
description="""
|
||||||
The word to search for within a selected book.
|
The word to search for within a selected book.
|
||||||
Note: Accepts single words only.
|
Note: Accepts single words only.
|
||||||
"""),
|
"""),
|
||||||
|
Parameter('account', kind=str, mandatory=False,
|
||||||
|
description="""
|
||||||
|
If you are running this workload on a device which has more than one
|
||||||
|
Google account setup, then this parameter is used to select which account
|
||||||
|
to select when prompted.
|
||||||
|
The account requires the book to have already been purchased or payment details
|
||||||
|
already associated with the account.
|
||||||
|
If omitted, the first account in the list will be selected if prompted.
|
||||||
|
"""),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# This workload relies on the internet so check that there is a working
|
||||||
|
# internet connection
|
||||||
requires_network = True
|
requires_network = True
|
||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
super(Googleplaybooks, self).validate()
|
super(Googleplaybooks, self).validate()
|
||||||
self.uiauto_params['book_title'] = self.search_book_title.replace(" ", "0space0")
|
self.uiauto_params['search_book_title'] = self.search_book_title.replace(' ', '0space0')
|
||||||
|
# If library_book_title is blank, set it to the same as search_book_title
|
||||||
|
if not self.library_book_title: # pylint: disable=access-member-before-definition
|
||||||
|
self.library_book_title = self.search_book_title # pylint: disable=attribute-defined-outside-init
|
||||||
|
self.uiauto_params['library_book_title'] = self.library_book_title.replace(' ', '0space0')
|
||||||
self.uiauto_params['chapter_page_number'] = self.select_chapter_page_number
|
self.uiauto_params['chapter_page_number'] = self.select_chapter_page_number
|
||||||
self.uiauto_params['search_word'] = self.search_word
|
self.uiauto_params['search_word'] = self.search_word
|
||||||
|
self.uiauto_params['account'] = self.account
|
||||||
|
Binary file not shown.
@ -26,13 +26,18 @@ import com.android.uiautomator.core.UiScrollable;
|
|||||||
|
|
||||||
import com.arm.wlauto.uiauto.UxPerfUiAutomation;
|
import com.arm.wlauto.uiauto.UxPerfUiAutomation;
|
||||||
|
|
||||||
|
import static com.arm.wlauto.uiauto.BaseUiAutomation.FindByCriteria.BY_ID;
|
||||||
|
import static com.arm.wlauto.uiauto.BaseUiAutomation.FindByCriteria.BY_TEXT;
|
||||||
|
import static com.arm.wlauto.uiauto.BaseUiAutomation.FindByCriteria.BY_DESC;
|
||||||
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import android.util.Log;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
public class UiAutomation extends UxPerfUiAutomation {
|
public class UiAutomation extends UxPerfUiAutomation {
|
||||||
|
|
||||||
protected Bundle parameters;
|
protected Bundle parameters;
|
||||||
@ -43,25 +48,31 @@ public class UiAutomation extends UxPerfUiAutomation {
|
|||||||
private long viewTimeout = TimeUnit.SECONDS.toMillis(viewTimeoutSecs);
|
private long viewTimeout = TimeUnit.SECONDS.toMillis(viewTimeoutSecs);
|
||||||
|
|
||||||
public void runUiAutomation() throws Exception {
|
public void runUiAutomation() throws Exception {
|
||||||
|
// Override superclass value
|
||||||
this.uiAutoTimeout = TimeUnit.SECONDS.toMillis(8);
|
this.uiAutoTimeout = TimeUnit.SECONDS.toMillis(8);
|
||||||
|
|
||||||
parameters = getParams();
|
parameters = getParams();
|
||||||
packageName = parameters.getString("package");
|
packageName = parameters.getString("package");
|
||||||
packageID = packageName + ":id/";
|
packageID = packageName + ":id/";
|
||||||
|
|
||||||
String bookTitle = parameters.getString("book_title").replace("0space0", " ");
|
String searchBookTitle = parameters.getString("search_book_title").replace("0space0", " ");
|
||||||
|
String libraryBookTitle = parameters.getString("library_book_title").replace("0space0", " ");
|
||||||
String chapterPageNumber = parameters.getString("chapter_page_number");
|
String chapterPageNumber = parameters.getString("chapter_page_number");
|
||||||
String searchWord = parameters.getString("search_word");
|
String searchWord = parameters.getString("search_word");
|
||||||
String noteText = "This is a test note";
|
String noteText = "This is a test note";
|
||||||
|
String account = parameters.getString("account");
|
||||||
|
|
||||||
setScreenOrientation(ScreenOrientation.NATURAL);
|
setScreenOrientation(ScreenOrientation.NATURAL);
|
||||||
|
|
||||||
|
chooseAccount(account);
|
||||||
clearFirstRunDialogues();
|
clearFirstRunDialogues();
|
||||||
|
dismissSendBooksAsGiftsDialog();
|
||||||
dismissSync();
|
dismissSync();
|
||||||
|
|
||||||
searchForBook(bookTitle);
|
searchForBook(searchBookTitle);
|
||||||
addToLibrary();
|
addToLibrary();
|
||||||
openMyLibrary();
|
openMyLibrary();
|
||||||
openBook(bookTitle);
|
openBook(libraryBookTitle);
|
||||||
|
|
||||||
UiWatcher pageSyncPopUpWatcher = createPopUpWatcher();
|
UiWatcher pageSyncPopUpWatcher = createPopUpWatcher();
|
||||||
registerWatcher("pageSyncPopUp", pageSyncPopUpWatcher);
|
registerWatcher("pageSyncPopUp", pageSyncPopUpWatcher);
|
||||||
@ -77,45 +88,38 @@ public class UiAutomation extends UxPerfUiAutomation {
|
|||||||
|
|
||||||
removeWatcher("pageSyncPop");
|
removeWatcher("pageSyncPop");
|
||||||
pressBack();
|
pressBack();
|
||||||
|
|
||||||
unsetScreenOrientation();
|
unsetScreenOrientation();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates a watcher for when a pop up warning appears when pages are out
|
// If the device has more than one account setup, a prompt appears
|
||||||
// of sync across multiple devices.
|
// In this case, select the first account in the list, unless `account`
|
||||||
private UiWatcher createPopUpWatcher() throws Exception {
|
// has been specified as a parameter, otherwise select `account`.
|
||||||
UiWatcher pageSyncPopUpWatcher = new UiWatcher() {
|
private void chooseAccount(String account) throws Exception {
|
||||||
|
UiObject accountPopup =
|
||||||
@Override
|
new UiObject(new UiSelector().textContains("Choose an account")
|
||||||
public boolean checkForCondition() {
|
.className("android.widget.TextView"));
|
||||||
UiObject popUpDialogue =
|
if (accountPopup.exists()) {
|
||||||
new UiObject(new UiSelector().resourceId("android:id/message")
|
if ("None".equals(account)) {
|
||||||
.textStartsWith("You're on page"));
|
// If no account has been specified, pick the first entry in the list
|
||||||
|
UiObject list =
|
||||||
// Don't sync and stay on the current page
|
new UiObject(new UiSelector().className("android.widget.ListView"));
|
||||||
if (popUpDialogue.exists()) {
|
UiObject first = list.getChild(new UiSelector().index(0));
|
||||||
try {
|
if (!first.exists()) {
|
||||||
UiObject stayOnPage = new UiObject(new UiSelector()
|
// Some devices are not zero indexed. If 0 doesnt exist, pick 1
|
||||||
.className("android.widget.Button")
|
first = list.getChild(new UiSelector().index(1));
|
||||||
.text("Yes"));
|
|
||||||
stayOnPage.click();
|
|
||||||
} catch (UiObjectNotFoundException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return popUpDialogue.waitUntilGone(viewTimeout);
|
|
||||||
}
|
}
|
||||||
return false;
|
first.click();
|
||||||
|
} else {
|
||||||
|
// Account specified, select that
|
||||||
|
clickUiObject(BY_TEXT, account, "android.widget.CheckedTextView");
|
||||||
}
|
}
|
||||||
};
|
// Click OK to proceed
|
||||||
|
UiObject ok =
|
||||||
return pageSyncPopUpWatcher;
|
new UiObject(new UiSelector().textContains("OK")
|
||||||
}
|
.className("android.widget.Button")
|
||||||
|
.enabled(true));
|
||||||
private void dismissSync() throws Exception {
|
ok.clickAndWaitForNewWindow();
|
||||||
UiObject keepSyncOff =
|
|
||||||
new UiObject(new UiSelector().textContains("Keep sync off")
|
|
||||||
.className("android.widget.Button"));
|
|
||||||
if (keepSyncOff.exists()) {
|
|
||||||
keepSyncOff.click();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,7 +129,6 @@ public class UiAutomation extends UxPerfUiAutomation {
|
|||||||
private void clearFirstRunDialogues() throws Exception {
|
private void clearFirstRunDialogues() throws Exception {
|
||||||
UiObject startButton =
|
UiObject startButton =
|
||||||
new UiObject(new UiSelector().resourceId(packageID + "start_button"));
|
new UiObject(new UiSelector().resourceId(packageID + "start_button"));
|
||||||
|
|
||||||
// First try and skip the sample book selection
|
// First try and skip the sample book selection
|
||||||
if (startButton.exists()) {
|
if (startButton.exists()) {
|
||||||
startButton.click();
|
startButton.click();
|
||||||
@ -133,7 +136,6 @@ public class UiAutomation extends UxPerfUiAutomation {
|
|||||||
|
|
||||||
UiObject endButton =
|
UiObject endButton =
|
||||||
new UiObject(new UiSelector().resourceId(packageID + "end_button"));
|
new UiObject(new UiSelector().resourceId(packageID + "end_button"));
|
||||||
|
|
||||||
// Click next button if it exists
|
// Click next button if it exists
|
||||||
if (endButton.exists()) {
|
if (endButton.exists()) {
|
||||||
endButton.click();
|
endButton.click();
|
||||||
@ -148,49 +150,65 @@ public class UiAutomation extends UxPerfUiAutomation {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void dismissSendBooksAsGiftsDialog() throws Exception {
|
||||||
|
UiObject gotIt =
|
||||||
|
new UiObject(new UiSelector().textContains("GOT IT!"));
|
||||||
|
if (gotIt.exists()) {
|
||||||
|
gotIt.click();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void dismissSync() throws Exception {
|
||||||
|
UiObject keepSyncOff =
|
||||||
|
new UiObject(new UiSelector().textContains("Keep sync off")
|
||||||
|
.className("android.widget.Button"));
|
||||||
|
if (keepSyncOff.exists()) {
|
||||||
|
keepSyncOff.click();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Searches for a "free" or "purchased" book title in Google play
|
// Searches for a "free" or "purchased" book title in Google play
|
||||||
private void searchForBook(final String bookTitle) throws Exception {
|
private void searchForBook(final String bookTitle) throws Exception {
|
||||||
UiObject search =
|
UiObject search =
|
||||||
new UiObject(new UiSelector().resourceId(packageID + "menu_search"));
|
new UiObject(new UiSelector().resourceId(packageID + "menu_search"));
|
||||||
|
if (!search.exists()) {
|
||||||
|
search =
|
||||||
|
new UiObject(new UiSelector().resourceId(packageID + "search_box_active_text_view"));
|
||||||
|
}
|
||||||
search.click();
|
search.click();
|
||||||
|
|
||||||
UiObject searchText = new UiObject(new UiSelector().textContains("Search")
|
UiObject searchText =
|
||||||
.className("android.widget.EditText"));
|
new UiObject(new UiSelector().textContains("Search")
|
||||||
|
.className("android.widget.EditText"));
|
||||||
searchText.setText(bookTitle);
|
searchText.setText(bookTitle);
|
||||||
pressEnter();
|
pressEnter();
|
||||||
|
|
||||||
UiObject resultList =
|
UiObject resultList =
|
||||||
new UiObject(new UiSelector().resourceId("com.android.vending:id/search_results_list"));
|
new UiObject(new UiSelector().resourceId("com.android.vending:id/search_results_list"));
|
||||||
|
|
||||||
if (!resultList.waitForExists(viewTimeout)) {
|
if (!resultList.waitForExists(viewTimeout)) {
|
||||||
throw new UiObjectNotFoundException("Could not find \"search results list view\".");
|
throw new UiObjectNotFoundException("Could not find \"search results list view\".");
|
||||||
}
|
}
|
||||||
|
|
||||||
String desc = String.format("Book: " + bookTitle);
|
|
||||||
|
|
||||||
// Create a selector so that we can search for siblings of the desired
|
// Create a selector so that we can search for siblings of the desired
|
||||||
// book that contains a "free" or "purchased" book identifier
|
// book that contains a "free" or "purchased" book identifier
|
||||||
UiSelector bookSelector = new UiSelector().description(desc).className("android.widget.TextView");
|
|
||||||
|
|
||||||
UiObject label =
|
UiObject label =
|
||||||
new UiObject(new UiSelector().fromParent(bookSelector)
|
new UiObject(new UiSelector().fromParent(new UiSelector()
|
||||||
|
.description(String.format("Book: " + bookTitle))
|
||||||
|
.className("android.widget.TextView"))
|
||||||
.resourceId("com.android.vending:id/li_label")
|
.resourceId("com.android.vending:id/li_label")
|
||||||
.descriptionMatches("^(Purchased|Free)$"));
|
.descriptionMatches("^(Purchased|Free)$"));
|
||||||
|
|
||||||
UiScrollable searchResultsList =
|
|
||||||
new UiScrollable(new UiSelector().resourceId("com.android.vending:id/search_results_list"));
|
|
||||||
|
|
||||||
final int maxSearchTime = 30;
|
final int maxSearchTime = 30;
|
||||||
int searchTime = maxSearchTime;
|
int searchTime = maxSearchTime;
|
||||||
|
|
||||||
while (!label.exists()) {
|
while (!label.exists()) {
|
||||||
if (searchTime <= 0) {
|
if (searchTime > 0) {
|
||||||
throw new UiObjectNotFoundException(
|
|
||||||
"Exceeded maximum search time (" + maxSearchTime + " seconds) to find book \"" + bookTitle + "\"");
|
|
||||||
} else {
|
|
||||||
uiDeviceSwipeDown(100);
|
uiDeviceSwipeDown(100);
|
||||||
sleep(1);
|
sleep(1);
|
||||||
searchTime--;
|
searchTime--;
|
||||||
|
} else {
|
||||||
|
throw new UiObjectNotFoundException(
|
||||||
|
"Exceeded maximum search time (" + maxSearchTime + " seconds) to find book \"" + bookTitle + "\"");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -200,18 +218,22 @@ public class UiAutomation extends UxPerfUiAutomation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void addToLibrary() throws Exception {
|
private void addToLibrary() throws Exception {
|
||||||
UiObject add = new UiObject(new UiSelector().textContains("ADD TO LIBRARY")
|
UiObject add =
|
||||||
.className("android.widget.Button"));
|
new UiObject(new UiSelector().textContains("ADD TO LIBRARY")
|
||||||
|
.className("android.widget.Button"));
|
||||||
if (add.exists()) {
|
if (add.exists()) {
|
||||||
add.click(); // add to My Library and opens book by default
|
// add to My Library and opens book by default
|
||||||
|
add.click();
|
||||||
|
clickUiObject(BY_TEXT, "BUY", "android.widget.Button", true);
|
||||||
} else {
|
} else {
|
||||||
UiObject read = getUiObjectByText("READ", "android.widget.Button");
|
// opens book
|
||||||
read.click(); // opens book
|
clickUiObject(BY_TEXT, "READ", "android.widget.Button");
|
||||||
}
|
}
|
||||||
|
|
||||||
waitForPage();
|
waitForPage();
|
||||||
|
|
||||||
UiObject navigationButton = new UiObject(new UiSelector().description("Navigate up"));
|
UiObject navigationButton =
|
||||||
|
new UiObject(new UiSelector().description("Navigate up"));
|
||||||
|
|
||||||
// Return to main app window
|
// Return to main app window
|
||||||
pressBack();
|
pressBack();
|
||||||
@ -227,15 +249,14 @@ public class UiAutomation extends UxPerfUiAutomation {
|
|||||||
private void openMyLibrary() throws Exception {
|
private void openMyLibrary() throws Exception {
|
||||||
String testTag = "open_library";
|
String testTag = "open_library";
|
||||||
ActionLogger logger = new ActionLogger(testTag, parameters);
|
ActionLogger logger = new ActionLogger(testTag, parameters);
|
||||||
|
|
||||||
logger.start();
|
logger.start();
|
||||||
|
clickUiObject(BY_DESC, "Show navigation drawer");
|
||||||
UiObject openDrawer = getUiObjectByDescription("Show navigation drawer");
|
|
||||||
openDrawer.click();
|
|
||||||
|
|
||||||
// To correctly find the UiObject we need to specify the index also here
|
// To correctly find the UiObject we need to specify the index also here
|
||||||
UiObject myLibrary =
|
UiObject myLibrary =
|
||||||
new UiObject(new UiSelector().className("android.widget.TextView")
|
new UiObject(new UiSelector().className("android.widget.TextView")
|
||||||
.text("My library").index(3));
|
.text("My library")
|
||||||
|
.index(3));
|
||||||
myLibrary.clickAndWaitForNewWindow(uiAutoTimeout);
|
myLibrary.clickAndWaitForNewWindow(uiAutoTimeout);
|
||||||
logger.stop();
|
logger.stop();
|
||||||
}
|
}
|
||||||
@ -244,31 +265,24 @@ public class UiAutomation extends UxPerfUiAutomation {
|
|||||||
String testTag = "open_book";
|
String testTag = "open_book";
|
||||||
ActionLogger logger = new ActionLogger(testTag, parameters);
|
ActionLogger logger = new ActionLogger(testTag, parameters);
|
||||||
|
|
||||||
UiScrollable cardsGrid =
|
long maxWaitTimeSeconds = 120;
|
||||||
new UiScrollable(new UiSelector().resourceId(packageID + "cards_grid"));
|
long maxWaitTime = TimeUnit.SECONDS.toMillis(maxWaitTimeSeconds);
|
||||||
|
|
||||||
UiSelector bookSelector = new UiSelector().text(bookTitle).className("android.widget.TextView");
|
UiSelector bookSelector =
|
||||||
|
new UiSelector().text(bookTitle)
|
||||||
|
.className("android.widget.TextView");
|
||||||
UiObject book = new UiObject(bookSelector);
|
UiObject book = new UiObject(bookSelector);
|
||||||
|
|
||||||
// Check that books are sorted by time added to library. This way we
|
// Check that books are sorted by time added to library. This way we
|
||||||
// can assume any newly downloaded books will be visible on the first
|
// can assume any newly downloaded books will be visible on the first
|
||||||
// screen.
|
// screen.
|
||||||
UiObject menuSort =
|
clickUiObject(BY_ID, packageID + "menu_sort", "android.widget.TextView");
|
||||||
getUiObjectByResourceId(packageID + "menu_sort", "android.widget.TextView");
|
clickUiObject(BY_TEXT, "Recent", "android.widget.TextView");
|
||||||
menuSort.click();
|
|
||||||
|
|
||||||
UiObject sortByRecent = getUiObjectByText("Recent", "android.widget.TextView");
|
|
||||||
sortByRecent.click();
|
|
||||||
|
|
||||||
// When the book is first added to library it may not appear in
|
// When the book is first added to library it may not appear in
|
||||||
// cardsGrid until it has been fully downloaded. Wait for fully
|
// cardsGrid until it has been fully downloaded. Wait for fully
|
||||||
// downloaded books
|
// downloaded books
|
||||||
UiObject downloadComplete =
|
UiObject downloadComplete =
|
||||||
new UiObject(new UiSelector().fromParent(bookSelector).description("100% downloaded"));
|
new UiObject(new UiSelector().fromParent(bookSelector)
|
||||||
|
.description("100% downloaded"));
|
||||||
long maxWaitTimeSeconds = 120;
|
|
||||||
long maxWaitTime = TimeUnit.SECONDS.toMillis(maxWaitTimeSeconds);
|
|
||||||
|
|
||||||
if (!downloadComplete.waitForExists(maxWaitTime)) {
|
if (!downloadComplete.waitForExists(maxWaitTime)) {
|
||||||
throw new UiObjectNotFoundException(
|
throw new UiObjectNotFoundException(
|
||||||
"Exceeded maximum wait time (" + maxWaitTimeSeconds + " seconds) to download book \"" + bookTitle + "\"");
|
"Exceeded maximum wait time (" + maxWaitTimeSeconds + " seconds) to download book \"" + bookTitle + "\"");
|
||||||
@ -280,6 +294,50 @@ public class UiAutomation extends UxPerfUiAutomation {
|
|||||||
logger.stop();
|
logger.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Creates a watcher for when a pop up warning appears when pages are out
|
||||||
|
// of sync across multiple devices.
|
||||||
|
private UiWatcher createPopUpWatcher() throws Exception {
|
||||||
|
UiWatcher pageSyncPopUpWatcher = new UiWatcher() {
|
||||||
|
@Override
|
||||||
|
public boolean checkForCondition() {
|
||||||
|
UiObject popUpDialogue =
|
||||||
|
new UiObject(new UiSelector().textStartsWith("You're on page")
|
||||||
|
.resourceId("android:id/message"));
|
||||||
|
// Don't sync and stay on the current page
|
||||||
|
if (popUpDialogue.exists()) {
|
||||||
|
try {
|
||||||
|
UiObject stayOnPage =
|
||||||
|
new UiObject(new UiSelector().text("Yes")
|
||||||
|
.className("android.widget.Button"));
|
||||||
|
stayOnPage.click();
|
||||||
|
} catch (UiObjectNotFoundException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return popUpDialogue.waitUntilGone(viewTimeout);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return pageSyncPopUpWatcher;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void selectChapter(final String chapterPageNumber) throws Exception {
|
||||||
|
getDropdownMenu();
|
||||||
|
|
||||||
|
UiObject contents = getUiObjectByResourceId(packageID + "menu_reader_toc");
|
||||||
|
contents.clickAndWaitForNewWindow(uiAutoTimeout);
|
||||||
|
UiObject toChapterView = getUiObjectByResourceId(packageID + "toc_list_view",
|
||||||
|
"android.widget.ExpandableListView");
|
||||||
|
// Navigate to top of chapter view
|
||||||
|
searchPage(toChapterView, "1", Direction.UP, 10);
|
||||||
|
// Search for chapter page number
|
||||||
|
UiObject page = searchPage(toChapterView, chapterPageNumber, Direction.DOWN, 10);
|
||||||
|
// Go to the page
|
||||||
|
page.clickAndWaitForNewWindow(viewTimeout);
|
||||||
|
|
||||||
|
waitForPage();
|
||||||
|
}
|
||||||
|
|
||||||
private void gesturesTest() throws Exception {
|
private void gesturesTest() throws Exception {
|
||||||
String testTag = "gesture";
|
String testTag = "gesture";
|
||||||
|
|
||||||
@ -324,72 +382,28 @@ public class UiAutomation extends UxPerfUiAutomation {
|
|||||||
waitForPage();
|
waitForPage();
|
||||||
}
|
}
|
||||||
|
|
||||||
private UiObject searchPage(final UiObject view, final String pagenum, final Direction updown,
|
|
||||||
final int attempts) throws Exception {
|
|
||||||
if (attempts <= 0) {
|
|
||||||
throw new UiObjectNotFoundException("Could not find \"page number\" after several attempts.");
|
|
||||||
}
|
|
||||||
|
|
||||||
String search = String.format("page " + pagenum);
|
|
||||||
UiObject page = new UiObject(new UiSelector().description(search)
|
|
||||||
.className("android.widget.TextView"));
|
|
||||||
if (!page.exists()) {
|
|
||||||
// Scroll up by swiping down
|
|
||||||
if (updown == Direction.UP) {
|
|
||||||
view.swipeDown(200);
|
|
||||||
// Default case is to scroll down (swipe up)
|
|
||||||
} else {
|
|
||||||
view.swipeUp(200);
|
|
||||||
}
|
|
||||||
searchPage(view, pagenum, updown, attempts - 1);
|
|
||||||
}
|
|
||||||
return page;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void selectChapter(final String chapterPageNumber) throws Exception {
|
|
||||||
getDropdownMenu();
|
|
||||||
|
|
||||||
UiObject contents = getUiObjectByResourceId(packageID + "menu_reader_toc");
|
|
||||||
contents.clickAndWaitForNewWindow(uiAutoTimeout);
|
|
||||||
|
|
||||||
UiObject toChapterView = getUiObjectByResourceId(packageID + "toc_list_view",
|
|
||||||
"android.widget.ExpandableListView");
|
|
||||||
|
|
||||||
// Navigate to top of chapter view
|
|
||||||
searchPage(toChapterView, "1", Direction.UP, 10);
|
|
||||||
|
|
||||||
UiObject page = searchPage(toChapterView, chapterPageNumber, Direction.DOWN, 10);
|
|
||||||
|
|
||||||
page.clickAndWaitForNewWindow(viewTimeout);
|
|
||||||
|
|
||||||
waitForPage();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addNote(final String text) throws Exception {
|
private void addNote(final String text) throws Exception {
|
||||||
String testTag = "note_add";
|
String testTag = "note_add";
|
||||||
ActionLogger logger = new ActionLogger(testTag, parameters);
|
ActionLogger logger = new ActionLogger(testTag, parameters);
|
||||||
|
|
||||||
hideDropDownMenu();
|
hideDropDownMenu();
|
||||||
|
|
||||||
|
UiObject clickable = new UiObject(new UiSelector().longClickable(true));
|
||||||
|
|
||||||
logger.start();
|
logger.start();
|
||||||
|
|
||||||
UiObject clickable = new UiObject(new UiSelector().longClickable(true));
|
|
||||||
uiObjectPerformLongClick(clickable, 100);
|
uiObjectPerformLongClick(clickable, 100);
|
||||||
|
|
||||||
UiObject addNoteButton = new UiObject(
|
UiObject addNoteButton =
|
||||||
new UiSelector().resourceId(packageID + "add_note_button"));
|
new UiObject(new UiSelector().resourceId(packageID + "add_note_button"));
|
||||||
addNoteButton.click();
|
addNoteButton.click();
|
||||||
|
|
||||||
UiObject noteEditText = getUiObjectByResourceId(packageID + "note_edit_text",
|
UiObject noteEditText = getUiObjectByResourceId(packageID + "note_edit_text",
|
||||||
"android.widget.EditText");
|
"android.widget.EditText");
|
||||||
noteEditText.setText(text);
|
noteEditText.setText(text);
|
||||||
|
|
||||||
UiObject noteMenuButton = getUiObjectByResourceId(packageID + "note_menu_button",
|
clickUiObject(BY_ID, packageID + "note_menu_button", "android.widget.ImageButton");
|
||||||
"android.widget.ImageButton");
|
clickUiObject(BY_TEXT, "Save", "android.widget.TextView");
|
||||||
noteMenuButton.click();
|
|
||||||
|
|
||||||
UiObject saveButton = getUiObjectByText("Save", "android.widget.TextView");
|
|
||||||
saveButton.click();
|
|
||||||
|
|
||||||
logger.stop();
|
logger.stop();
|
||||||
|
|
||||||
@ -399,17 +413,18 @@ public class UiAutomation extends UxPerfUiAutomation {
|
|||||||
private void removeNote() throws Exception {
|
private void removeNote() throws Exception {
|
||||||
String testTag = "note_remove";
|
String testTag = "note_remove";
|
||||||
ActionLogger logger = new ActionLogger(testTag, parameters);
|
ActionLogger logger = new ActionLogger(testTag, parameters);
|
||||||
logger.start();
|
|
||||||
|
|
||||||
UiObject clickable = new UiObject(new UiSelector().longClickable(true));
|
UiObject clickable = new UiObject(new UiSelector().longClickable(true));
|
||||||
|
|
||||||
|
logger.start();
|
||||||
|
|
||||||
uiObjectPerformLongClick(clickable, 100);
|
uiObjectPerformLongClick(clickable, 100);
|
||||||
|
|
||||||
UiObject removeButton = new UiObject(
|
UiObject removeButton =
|
||||||
new UiSelector().resourceId(packageID + "remove_highlight_button"));
|
new UiObject(new UiSelector().resourceId(packageID + "remove_highlight_button"));
|
||||||
removeButton.click();
|
removeButton.click();
|
||||||
|
|
||||||
UiObject confirmRemove = getUiObjectByText("Remove", "android.widget.Button");
|
clickUiObject(BY_TEXT, "Remove", "android.widget.Button");
|
||||||
confirmRemove.click();
|
|
||||||
|
|
||||||
logger.stop();
|
logger.stop();
|
||||||
|
|
||||||
@ -420,26 +435,25 @@ public class UiAutomation extends UxPerfUiAutomation {
|
|||||||
String testTag = "search_word";
|
String testTag = "search_word";
|
||||||
ActionLogger logger = new ActionLogger(testTag, parameters);
|
ActionLogger logger = new ActionLogger(testTag, parameters);
|
||||||
|
|
||||||
|
// Allow extra time for search queries involing high freqency words
|
||||||
|
final long searchTimeout = TimeUnit.SECONDS.toMillis(20);
|
||||||
|
|
||||||
getDropdownMenu();
|
getDropdownMenu();
|
||||||
|
|
||||||
UiObject search = new UiObject(
|
UiObject search =
|
||||||
new UiSelector().resourceId(packageID + "menu_search"));
|
new UiObject(new UiSelector().resourceId(packageID + "menu_search"));
|
||||||
search.click();
|
search.click();
|
||||||
|
|
||||||
UiObject searchText = new UiObject(
|
UiObject searchText =
|
||||||
new UiSelector().resourceId(packageID + "search_src_text"));
|
new UiObject(new UiSelector().resourceId(packageID + "search_src_text"));
|
||||||
|
|
||||||
logger.start();
|
logger.start();
|
||||||
|
|
||||||
searchText.setText(text);
|
searchText.setText(text);
|
||||||
pressEnter();
|
pressEnter();
|
||||||
|
|
||||||
UiObject resultList = new UiObject(
|
UiObject resultList =
|
||||||
new UiSelector().resourceId(packageID + "search_results_list"));
|
new UiObject(new UiSelector().resourceId(packageID + "search_results_list"));
|
||||||
|
|
||||||
// Allow extra time for search queries involing high freqency words
|
|
||||||
final long searchTimeout = TimeUnit.SECONDS.toMillis(20);
|
|
||||||
|
|
||||||
if (!resultList.waitForExists(searchTimeout)) {
|
if (!resultList.waitForExists(searchTimeout)) {
|
||||||
throw new UiObjectNotFoundException("Could not find \"search results list view\".");
|
throw new UiObjectNotFoundException("Could not find \"search results list view\".");
|
||||||
}
|
}
|
||||||
@ -447,7 +461,6 @@ public class UiAutomation extends UxPerfUiAutomation {
|
|||||||
UiObject searchWeb =
|
UiObject searchWeb =
|
||||||
new UiObject(new UiSelector().text("Search web")
|
new UiObject(new UiSelector().text("Search web")
|
||||||
.className("android.widget.TextView"));
|
.className("android.widget.TextView"));
|
||||||
|
|
||||||
if (!searchWeb.waitForExists(searchTimeout)) {
|
if (!searchWeb.waitForExists(searchTimeout)) {
|
||||||
throw new UiObjectNotFoundException("Could not find \"Search web view\".");
|
throw new UiObjectNotFoundException("Could not find \"Search web view\".");
|
||||||
}
|
}
|
||||||
@ -461,27 +474,27 @@ public class UiAutomation extends UxPerfUiAutomation {
|
|||||||
String testTag = "style";
|
String testTag = "style";
|
||||||
|
|
||||||
getDropdownMenu();
|
getDropdownMenu();
|
||||||
UiObject readerSettings = getUiObjectByResourceId(packageID + "menu_reader_settings",
|
|
||||||
"android.widget.TextView");
|
clickUiObject(BY_ID, packageID + "menu_reader_settings", "android.widget.TextView");
|
||||||
readerSettings.click();
|
|
||||||
|
|
||||||
// Check for lighting option button on newer versions
|
// Check for lighting option button on newer versions
|
||||||
UiObject lightingOptionsButton =
|
UiObject lightingOptionsButton =
|
||||||
new UiObject(new UiSelector().resourceId(packageID + "lighting_options_button"));
|
new UiObject(new UiSelector().resourceId(packageID + "lighting_options_button"));
|
||||||
|
|
||||||
if (lightingOptionsButton.exists()) {
|
if (lightingOptionsButton.exists()) {
|
||||||
lightingOptionsButton.click();
|
lightingOptionsButton.click();
|
||||||
}
|
}
|
||||||
|
|
||||||
String[] styles = {"Night", "Sepia", "Day"};
|
String[] styles = {"Night", "Sepia", "Day"};
|
||||||
|
|
||||||
for (String style : styles) {
|
for (String style : styles) {
|
||||||
try {
|
try {
|
||||||
ActionLogger logger = new ActionLogger(testTag + "_" + style, parameters);
|
ActionLogger logger = new ActionLogger(testTag + "_" + style, parameters);
|
||||||
UiObject pageStyle = new UiObject(new UiSelector().description(style));
|
UiObject pageStyle =
|
||||||
|
new UiObject(new UiSelector().description(style));
|
||||||
|
|
||||||
logger.start();
|
logger.start();
|
||||||
pageStyle.clickAndWaitForNewWindow(viewTimeout);
|
pageStyle.clickAndWaitForNewWindow(viewTimeout);
|
||||||
logger.stop();
|
logger.stop();
|
||||||
|
|
||||||
} catch (UiObjectNotFoundException e) {
|
} catch (UiObjectNotFoundException e) {
|
||||||
// On some devices the lighting options menu disappears
|
// On some devices the lighting options menu disappears
|
||||||
// between clicks. Searching for the menu again would affect
|
// between clicks. Searching for the menu again would affect
|
||||||
@ -501,8 +514,7 @@ public class UiAutomation extends UxPerfUiAutomation {
|
|||||||
|
|
||||||
getDropdownMenu();
|
getDropdownMenu();
|
||||||
|
|
||||||
UiObject moreOptions = getUiObjectByDescription("More options", "android.widget.ImageView");
|
clickUiObject(BY_DESC, "More options", "android.widget.ImageView");
|
||||||
moreOptions.click();
|
|
||||||
|
|
||||||
UiObject bookInfo = getUiObjectByText("About this book", "android.widget.TextView");
|
UiObject bookInfo = getUiObjectByText("About this book", "android.widget.TextView");
|
||||||
|
|
||||||
@ -519,15 +531,51 @@ public class UiAutomation extends UxPerfUiAutomation {
|
|||||||
pressBack();
|
pressBack();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper for waiting on a page between actions
|
||||||
|
private UiObject waitForPage() throws Exception {
|
||||||
|
UiObject activityReader =
|
||||||
|
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
|
||||||
|
// becomes visible on the screen. Therefore add pause instead.
|
||||||
|
sleep(3);
|
||||||
|
|
||||||
|
if (!activityReader.waitForExists(viewTimeout)) {
|
||||||
|
throw new UiObjectNotFoundException("Could not find \"activity reader view\".");
|
||||||
|
}
|
||||||
|
|
||||||
|
return activityReader;
|
||||||
|
}
|
||||||
|
|
||||||
// Helper for accessing the drop down menu
|
// Helper for accessing the drop down menu
|
||||||
private void getDropdownMenu() throws Exception {
|
private void getDropdownMenu() throws Exception {
|
||||||
UiObject actionBar =
|
UiObject actionBar =
|
||||||
new UiObject(new UiSelector().resourceId(packageID + "action_bar"));
|
new UiObject(new UiSelector().resourceId(packageID + "action_bar"));
|
||||||
|
|
||||||
if (!actionBar.exists()) {
|
if (!actionBar.exists()) {
|
||||||
tapDisplayCentre();
|
tapDisplayCentre();
|
||||||
sleep(1); // Allow previous views to settle
|
sleep(1); // Allow previous views to settle
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UiObject card =
|
||||||
|
new UiObject(new UiSelector().resourceId(packageID + "cards")
|
||||||
|
.className("android.view.ViewGroup"));
|
||||||
|
if (card.exists()) {
|
||||||
|
// On rare occasions tapping a certain word that appears in the centre
|
||||||
|
// of the display will bring up a card to describe the word.
|
||||||
|
// (Such as a place will bring a map of its location)
|
||||||
|
// In this situation, tap centre to go back, and try again
|
||||||
|
// at a different set of coordinates
|
||||||
|
int x = (int)(getDisplayCentreWidth() * 0.8);
|
||||||
|
int y = (int)(getDisplayCentreHeight() * 0.8);
|
||||||
|
while (card.exists()) {
|
||||||
|
tapDisplay(x, y);
|
||||||
|
sleep(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
tapDisplay(x, y);
|
||||||
|
sleep(1); // Allow previous views to settle
|
||||||
|
}
|
||||||
|
|
||||||
if (!actionBar.exists()) {
|
if (!actionBar.exists()) {
|
||||||
throw new UiObjectNotFoundException("Could not find \"action bar\".");
|
throw new UiObjectNotFoundException("Could not find \"action bar\".");
|
||||||
@ -537,7 +585,6 @@ public class UiAutomation extends UxPerfUiAutomation {
|
|||||||
private void hideDropDownMenu() throws Exception {
|
private void hideDropDownMenu() throws Exception {
|
||||||
UiObject actionBar =
|
UiObject actionBar =
|
||||||
new UiObject(new UiSelector().resourceId(packageID + "action_bar"));
|
new UiObject(new UiSelector().resourceId(packageID + "action_bar"));
|
||||||
|
|
||||||
if (actionBar.exists()) {
|
if (actionBar.exists()) {
|
||||||
tapDisplayCentre();
|
tapDisplayCentre();
|
||||||
sleep(1); // Allow previous views to settle
|
sleep(1); // Allow previous views to settle
|
||||||
@ -548,20 +595,25 @@ public class UiAutomation extends UxPerfUiAutomation {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper for waiting on a page between actions
|
private UiObject searchPage(final UiObject view, final String pagenum, final Direction updown,
|
||||||
private UiObject waitForPage() throws Exception {
|
final int attempts) throws Exception {
|
||||||
UiObject activityReader =
|
if (attempts <= 0) {
|
||||||
new UiObject(new UiSelector().resourceId(packageID + "activity_reader")
|
throw new UiObjectNotFoundException("Could not find \"page number\" after several attempts.");
|
||||||
.childSelector(new UiSelector().focusable(true)));
|
|
||||||
|
|
||||||
// On some devices the object in the view hierarchy is found before it
|
|
||||||
// becomes visible on the screen. Therefore add pause instead.
|
|
||||||
sleep(3);
|
|
||||||
|
|
||||||
if (!activityReader.waitForExists(viewTimeout)) {
|
|
||||||
throw new UiObjectNotFoundException("Could not find \"activity reader view\".");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return activityReader;
|
UiObject page =
|
||||||
|
new UiObject(new UiSelector().description(String.format("page " + pagenum))
|
||||||
|
.className("android.widget.TextView"));
|
||||||
|
if (!page.exists()) {
|
||||||
|
// Scroll up by swiping down
|
||||||
|
if (updown == Direction.UP) {
|
||||||
|
view.swipeDown(200);
|
||||||
|
// Default case is to scroll down (swipe up)
|
||||||
|
} else {
|
||||||
|
view.swipeUp(200);
|
||||||
|
}
|
||||||
|
page = searchPage(view, pagenum, updown, attempts - 1);
|
||||||
|
}
|
||||||
|
return page;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user