1
0
mirror of https://github.com/ARM-software/workload-automation.git synced 2025-03-21 01:59:13 +00:00

Simplify parameters & improve reliability of slide show test

This commit is contained in:
muendelezaji 2016-05-20 13:45:08 +01:00 committed by muendelezaji
parent 354602fc73
commit edf2cb0e57
3 changed files with 77 additions and 101 deletions

View File

@ -47,21 +47,26 @@ class GoogleSlides(AndroidUiAutoBenchmark):
If ``True``, dumpsys captures will be carried out during the test run. If ``True``, dumpsys captures will be carried out during the test run.
The output is piped to log files which are then pulled from the phone. The output is piped to log files which are then pulled from the phone.
'''), '''),
Parameter('local_files', kind=list_of_strings, Parameter('local_file', kind=str,
description=''' description='''
If specified, the workload will push the PowerPoint files to be used for If specified, the workload will push the PowerPoint file to be used for
testing on the device. Otherwise, a file will be created inside the app. testing on the device. Otherwise, a file will be created inside the app.
'''), '''),
Parameter('slide_count', kind=int, default=5,
description='''
Number of slides in aforementioned local file. Determines number of
swipe actions when playing slide show.
'''),
] ]
instrumentation_log = '{}_instrumentation.log'.format(name) instrumentation_log = '{}_instrumentation.log'.format(name)
file_prefix = 'wa_test_'
device_dir = '/sdcard/Download'
local_dir = '.' # self.dependencies_directory
def __init__(self, device, **kwargs): def __init__(self, device, **kwargs):
super(GoogleSlides, self).__init__(device, **kwargs) super(GoogleSlides, self).__init__(device, **kwargs)
self.output_file = path.join(self.device.working_directory, self.instrumentation_log) self.output_file = path.join(self.device.working_directory, self.instrumentation_log)
self.local_dir = self.dependencies_directory
self.device_dir = path.join(self.device.working_directory, '..', 'Download') # Android downloads folder
self.wa_test_file = 'wa_test_' + self.local_file
self.run_timeout = 300 self.run_timeout = 300
def validate(self): def validate(self):
@ -70,22 +75,22 @@ class GoogleSlides(AndroidUiAutoBenchmark):
self.uiauto_params['dumpsys_enabled'] = self.dumpsys_enabled self.uiauto_params['dumpsys_enabled'] = self.dumpsys_enabled
self.uiauto_params['output_dir'] = self.device.working_directory self.uiauto_params['output_dir'] = self.device.working_directory
self.uiauto_params['results_file'] = self.output_file self.uiauto_params['results_file'] = self.output_file
if self.local_files: if self.local_file:
wa_files = [self.wa_filename(f) for f in self.local_files] self.uiauto_params['local_file'] = self.wa_test_file
self.uiauto_params['local_files'] = '::'.join(wa_files) self.uiauto_params['slide_count'] = self.slide_count
def initialize(self, context): def initialize(self, context):
log_method(self, 'initialize') log_method(self, 'initialize')
super(GoogleSlides, self).initialize(context) super(GoogleSlides, self).initialize(context)
if self.local_files: if self.local_file:
# push local PPT files # push local PPT file
for entry in os.listdir(self.local_dir): for entry in os.listdir(self.local_dir):
if entry.endswith('.pptx'): if entry is self.local_file:
self.device.push_file(path.join(self.local_dir, entry), self.device.push_file(path.join(self.local_dir, self.local_file),
path.join(self.device_dir, self.wa_filename(entry)), path.join(self.device_dir, self.wa_test_file),
timeout=60) timeout=60)
# Force a re-index of the mediaserver cache to pick up new files self.logger.info(path.join(self.local_dir, self.local_file))
# self.device.execute('am broadcast -a android.intent.action.MEDIA_MOUNTED -d file:///sdcard') self.logger.info(path.join(self.device_dir, self.wa_test_file))
def setup(self, context): def setup(self, context):
log_method(self, 'setup') log_method(self, 'setup')
@ -98,24 +103,21 @@ class GoogleSlides(AndroidUiAutoBenchmark):
def update_result(self, context): def update_result(self, context):
log_method(self, 'update_result') log_method(self, 'update_result')
super(GoogleSlides, self).update_result(context) super(GoogleSlides, self).update_result(context)
not_implemented(self, 'get_metrics(context)') not_implemented(self, 'self.get_metrics(context)')
def teardown(self, context): def teardown(self, context):
log_method(self, 'teardown') log_method(self, 'teardown')
super(GoogleSlides, self).teardown(context) super(GoogleSlides, self).teardown(context)
not_implemented(self, 'pull_logs(context)') not_implemented(self, 'self.pull_logs(context)')
self.device.execute('am broadcast -a android.intent.action.MEDIA_MOUNTED -d file:///sdcard')
def finalize(self, context): def finalize(self, context):
log_method(self, 'finalize') log_method(self, 'finalize')
super(GoogleSlides, self).finalize(context) super(GoogleSlides, self).finalize(context)
if self.local_files: if self.local_file:
# delete pushed PPT files # delete pushed PPT file
for entry in os.listdir(self.local_dir): for entry in self.device.listdir(self.device_dir):
if entry.endswith('.pptx'): if entry is self.wa_test_file:
self.device.delete_file(path.join(self.device_dir, self.wa_filename(entry))) self.device.delete_file(path.join(self.device_dir, entry))
# Force a re-index of the mediaserver cache to pick up new files
# self.device.execute('am broadcast -a android.intent.action.MEDIA_MOUNTED -d file:///sdcard')
def wa_filename(self, filename): def wa_filename(self, filename):
return self.file_prefix + filename return self.file_prefix + filename

View File

@ -53,8 +53,9 @@ public class UiAutomation extends UxPerfUiAutomation {
public static final int BY_DESC = 3; public static final int BY_DESC = 3;
public static final int ONE_SECOND_IN_MS = 1000; public static final int ONE_SECOND_IN_MS = 1000;
public static final int DEFAULT_SWIPE_STEPS = 20;
public static final String DOC_FILENAME = "UX Perf Slides"; public static final String NEW_DOC_FILENAME = "UX Perf Slides";
public static final String DOCUMENTATION_WORKLOADS = public static final String DOCUMENTATION_WORKLOADS =
"class Workload(Extension):\n\tname = None\n\tdef init_resources(self, context):\n\t\tpass\n" "class Workload(Extension):\n\tname = None\n\tdef init_resources(self, context):\n\t\tpass\n"
@ -77,16 +78,18 @@ public class UiAutomation extends UxPerfUiAutomation {
protected Bundle parameters; protected Bundle parameters;
protected boolean dumpsysEnabled; protected boolean dumpsysEnabled;
protected String outputDir; protected String outputDir;
protected String[] documents; protected String localFile;
protected boolean useLocalFiles; protected int slideCount;
protected boolean useLocalFile;
protected String resultsFile; protected String resultsFile;
public void parseParams(Bundle parameters) throws Exception { public void parseParams(Bundle parameters) throws Exception {
dumpsysEnabled = Boolean.parseBoolean(parameters.getString("dumpsys_enabled")); dumpsysEnabled = Boolean.parseBoolean(parameters.getString("dumpsys_enabled"));
outputDir = parameters.getString("output_dir"); outputDir = parameters.getString("output_dir");
resultsFile = parameters.getString("results_file"); resultsFile = parameters.getString("results_file");
documents = parameters.getString("local_files", "::").split("::"); localFile = parameters.getString("local_file", "");
useLocalFiles = documents.length != 0; slideCount = Integer.parseInt(parameters.getString("slide_count"));
useLocalFile = localFile != null;
} }
public void runUiAutomation() throws Exception { public void runUiAutomation() throws Exception {
@ -94,12 +97,11 @@ public class UiAutomation extends UxPerfUiAutomation {
parseParams(parameters); parseParams(parameters);
skipWelcomeScreen(); skipWelcomeScreen();
enablePowerpointCompat(); enablePowerpointCompat();
if (useLocalFiles) { if (useLocalFile) {
testSlideshowFromStorage(documents[0]); testSlideshowFromStorage(localFile);
} else { } else {
testEditNewSlidesDocument(DOC_FILENAME); testEditNewSlidesDocument(NEW_DOC_FILENAME);
} }
if (false) { // TODO currently unused if (false) { // TODO currently unused
writeResultsToFile(results, parameters.getString("results_file")); writeResultsToFile(results, parameters.getString("results_file"));
} }
@ -111,21 +113,21 @@ public class UiAutomation extends UxPerfUiAutomation {
} }
protected void enablePowerpointCompat() throws Exception { protected void enablePowerpointCompat() throws Exception {
uiDeviceEdgeSwipeFromLeft(10); uiDeviceSwipeHorizontal(0, getDisplayWidth()/2, getDisplayHeight()/2);
clickView(BY_TEXT, "Settings", true); clickView(BY_TEXT, "Settings", true);
clickView(BY_TEXT, "Create PowerPoint"); clickView(BY_TEXT, "Create PowerPoint");
getUiDevice().pressBack(); getUiDevice().pressBack();
sleep(1); sleep(1);
} }
protected void testSlideshowFromStorage(String document) throws Exception { protected void testSlideshowFromStorage(String docName) throws Exception {
// Sometimes docs deleted in __init__.py falsely appear on the app's home // Sometimes docs deleted in __init__.py falsely appear on the app's home
// For robustness, it's nice to remove these placeholders // For robustness, it's nice to remove these placeholders
// However, the test should not crash because of it, so a silent catch is used // However, the test should not crash because of it, so a silent catch is used
UiObject docView = new UiObject(new UiSelector().textContains(document)); UiObject docView = new UiObject(new UiSelector().textContains(docName));
if (docView.waitForExists(ONE_SECOND_IN_MS)) { if (docView.waitForExists(ONE_SECOND_IN_MS)) {
try { try {
deleteDocument(document); deleteDocument(docName);
} catch (Exception e) { } catch (Exception e) {
// do nothing // do nothing
} }
@ -137,24 +139,32 @@ public class UiAutomation extends UxPerfUiAutomation {
if (permissionView.waitForExists(ONE_SECOND_IN_MS)) { if (permissionView.waitForExists(ONE_SECOND_IN_MS)) {
clickView(BY_TEXT, "Allow"); clickView(BY_TEXT, "Allow");
} }
try { // Scroll through document list if necessary
clickView(BY_TEXT, document); UiScrollable list = new UiScrollable(new UiSelector().className("android.widget.ListView"));
} catch (UiObjectNotFoundException e) { list.scrollIntoView(new UiSelector().textContains(docName));
// Click failed, scroll down and retry clickView(BY_TEXT, docName);
UiScrollable list = new UiScrollable(new UiSelector().className("android.widget.ListView"));
list.scrollIntoView(new UiSelector().textContains(document));
clickView(BY_TEXT, document);
}
clickView(BY_TEXT, "Open", CLASS_BUTTON, true); clickView(BY_TEXT, "Open", CLASS_BUTTON, true);
sleep(5); sleep(5);
clickView(BY_DESC, "Start slideshow", true);
int centerY = getUiDevice().getDisplayHeight() / 2; int centerY = getUiDevice().getDisplayHeight() / 2;
int centerX = getUiDevice().getDisplayWidth() / 2; int centerX = getUiDevice().getDisplayWidth() / 2;
int slidesLeft = 10; int slidesLeft = slideCount - 1;
// scroll forward in edit mode
while (slidesLeft-- > 0) { while (slidesLeft-- > 0) {
getUiDevice().swipe(centerX + centerX/2, centerY, centerX - centerX/2, centerY, 20); uiDeviceSwipeHorizontal(centerX + centerX/2, centerX - centerX/2, centerY);
sleep(2); sleep(1);
}
sleep(1);
// scroll backward in edit mode
while (++slidesLeft < slideCount - 1) {
uiDeviceSwipeHorizontal(centerX - centerX/2, centerX + centerX/2, centerY);
sleep(1);
}
// scroll forward in slideshow mode
clickView(BY_DESC, "Start slideshow", true);
while (--slidesLeft > 0) {
uiDeviceSwipeHorizontal(centerX + centerX/2, centerX - centerX/2, centerY);
sleep(1);
} }
getUiDevice().pressBack(); getUiDevice().pressBack();
getUiDevice().pressBack(); getUiDevice().pressBack();
@ -230,6 +240,17 @@ public class UiAutomation extends UxPerfUiAutomation {
view.clickAndWaitForNewWindow(); view.clickAndWaitForNewWindow();
} }
public UiObject enterTextInSlide(String viewName, String textToEnter) throws Exception {
UiObject view = getViewByDesc(viewName);
view.click();
sleepMicro(100);
view.click(); // double click
view.setText(textToEnter);
getUiDevice().pressBack();
sleepMicro(200);
return view;
}
public void saveDocument(String docName) throws Exception { public void saveDocument(String docName) throws Exception {
clickView(BY_TEXT, "SAVE"); clickView(BY_TEXT, "SAVE");
clickView(BY_TEXT, "Device"); clickView(BY_TEXT, "Device");
@ -250,17 +271,6 @@ public class UiAutomation extends UxPerfUiAutomation {
sleep(1); sleep(1);
} }
public UiObject enterTextInSlide(String viewName, String textToEnter) throws Exception {
UiObject view = getViewByDesc(viewName);
view.click();
sleepMicro(100);
view.click(); // double click
view.setText(textToEnter);
getUiDevice().pressBack();
sleepMicro(200);
return view;
}
public void deleteDocument(String docName) throws Exception { public void deleteDocument(String docName) throws Exception {
UiObject doc = getViewByText(docName); UiObject doc = getViewByText(docName);
doc.longClick(); doc.longClick();
@ -345,47 +355,11 @@ public class UiAutomation extends UxPerfUiAutomation {
return object; return object;
} }
public void uiDeviceEdgeSwipeFromLeft(int steps) { public void uiDeviceSwipeHorizontal(int startX, int endX, int height) {
int height = getDisplayHeight(); uiDeviceSwipeHorizontal(startX, endX, height, DEFAULT_SWIPE_STEPS);
int width = getDisplayWidth();
getUiDevice().swipe(0, height/2, width/2, height/2, steps);
} }
public void tapDisplayNormalised(double percentX, double percentY) { public void uiDeviceSwipeHorizontal(int startX, int endX, int height, int steps) {
double x = Math.max(0, Math.min(1, percentX)); getUiDevice().swipe(startX, height, endX, height, steps);
double y = Math.max(0, Math.min(1, percentY));
int tapX = (int) Math.floor(x * getDisplayWidth());
int tapY = (int) Math.floor(y * getDisplayHeight());
getUiDevice().click(tapX, tapY);
}
public void toggleWifiState(boolean flag) throws Exception {
int exitValue = -1;
// To enable, check for "UninitializedState"
// String checkFor = flag ? "UninitializedState" : "ConnectedState";
// exitValue = runShellCommand("dumpsys wifi | grep curState=" + checkFor);
// if (0 == exitValue) { // toggle state
String statusString = flag ? "ConnectedState" : "UninitializedState";
exitValue = runShellCommand("dumpsys wifi | grep curState=" + statusString);
if (0 != exitValue) { // not in the expected so toggle it
String[] adbCommands = {
"am start -a android.intent.action.MAIN -n com.android.settings/.wifi.WifiSettings;",
"input keyevent 20;",
"input keyevent 23;",
"sleep 1;",
"input keyevent 4;",
};
for (String command : adbCommands) {
exitValue = runShellCommand(command);
}
}
sleep(1);
}
public int runShellCommand(String command) throws Exception {
Process proc = Runtime.getRuntime().exec(command);
Log.d(TAG, String.format("Command:\n%s\nExit value:%d\n", command, proc.exitValue()));
proc.waitFor();
return proc.exitValue();
} }
} }