From 441ba974b79bbf4bc815153e48cf08c44924263b Mon Sep 17 00:00:00 2001 From: muendelezaji Date: Wed, 24 Aug 2016 10:20:21 +0100 Subject: [PATCH] Youtube workload --- wlauto/workloads/youtube/__init__.py | 90 +++++++ .../youtube/com.arm.wlauto.uiauto.youtube.jar | Bin 0 -> 13046 bytes wlauto/workloads/youtube/uiauto/build.sh | 39 +++ wlauto/workloads/youtube/uiauto/build.xml | 92 +++++++ .../youtube/uiauto/project.properties | 14 + .../com/arm/wlauto/uiauto/UiAutomation.java | 239 ++++++++++++++++++ 6 files changed, 474 insertions(+) create mode 100755 wlauto/workloads/youtube/__init__.py create mode 100644 wlauto/workloads/youtube/com.arm.wlauto.uiauto.youtube.jar create mode 100755 wlauto/workloads/youtube/uiauto/build.sh create mode 100644 wlauto/workloads/youtube/uiauto/build.xml create mode 100644 wlauto/workloads/youtube/uiauto/project.properties create mode 100644 wlauto/workloads/youtube/uiauto/src/com/arm/wlauto/uiauto/UiAutomation.java diff --git a/wlauto/workloads/youtube/__init__.py b/wlauto/workloads/youtube/__init__.py new file mode 100755 index 00000000..bef245df --- /dev/null +++ b/wlauto/workloads/youtube/__init__.py @@ -0,0 +1,90 @@ +# Copyright 2014-2016 ARM Limited +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +from wlauto import AndroidUxPerfWorkload, Parameter +from wlauto.exceptions import WorkloadError + + +class Youtube(AndroidUxPerfWorkload): + + name = 'youtube' + package = 'com.google.android.youtube' + min_apk_version = '11.19.56' + max_apk_version = None # works with latest (11.33.58) at time of publishing this + activity = '' + description = ''' + A workload to perform standard productivity tasks within YouTube. + + The workload plays a video from the app, determined by the ``video_source`` parameter. + While the video is playing, a some common actions are done such as video seeking, pausing + playback and navigating the comments section. + + Test description: + The ``video_source`` parameter determines where the video to be played will be found + in the app. Possible values are ``search``, ``home``, ``my_videos``, and ``trending``. + -A. search - Goes to the search view, does a search for the given term, and plays the + first video in the results. The parameter ``search_term`` must also be provided + in the agenda for this to work. This is the default mode. + -B. home - Scrolls down once on the app's home page to avoid ads (if present, would be + first video), then select and plays the video that appears at the top of the list. + -C. my_videos - Goes to the 'My Videos' section of the user's account page and plays a + video from there. The user must have at least one uploaded video for this to work. + -D. trending - Goes to the 'Trending Videos' section of the app, and plays the first + video in the trending videos list. + + For the selected video source, the following test steps are performed: + 1. Navigate to the general app settings page to disable autoplay. This improves test + stability and predictability by preventing screen transition to load a new video + while in the middle of the test. + 2. Select the video from the source specified above, and dismiss any potential embedded + advert that may pop-up before the actual video. + 3. Let the video play for a few seconds, pause it, then resume. + 4. Expand the info card that shows video metadata, then collapse it again. + 5. Scroll down to the end of related videos and comments under the info card, and then + back up to the start. A maximum of 5 swipe actions is performed in either direction. + ''' + + parameters = [ + Parameter('video_source', kind=str, default='search', + allowed_values=['home', 'my_videos', 'search', 'trending'], + description=''' + Determines where to play the video from. This can either be from the + YouTube home, my videos section, trending videos or found in search. + '''), + Parameter('search_term', kind=str, + default='Big Buck Bunny 60fps 4K - Official Blender Foundation Short Film', + description=''' + The search term to use when ``video_source`` is set to ``search``. Ignored otherwise. + '''), + ] + + view = [ + package + '/com.google.android.apps.youtube.app.WatchWhileActivity', + package + '/com.google.android.apps.youtube.app.honeycomb.SettingsActivity', + ] + + requires_network = True + + def __init__(self, device, **kwargs): + super(Youtube, self).__init__(device, **kwargs) + self.run_timeout = 300 + + def validate(self): + if self.video_source == 'search' and not self.search_term: + raise WorkloadError("Param 'search_term' must be specified when video source is 'search'") + + self.uiauto_params['package'] = self.package + self.uiauto_params['video_source'] = self.video_source + self.uiauto_params['search_term'] = self.search_term.replace(' ', '0space0') diff --git a/wlauto/workloads/youtube/com.arm.wlauto.uiauto.youtube.jar b/wlauto/workloads/youtube/com.arm.wlauto.uiauto.youtube.jar new file mode 100644 index 0000000000000000000000000000000000000000..218135c5468c9c5554e0ad86b01402375abae1c4 GIT binary patch literal 13046 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/dev/null`; then + script_path=`readlink -f $0 2>/dev/null` +fi +script_dir=`dirname $script_path` +cd $script_dir + +# Ensure build.xml exists before starting +if [[ ! -f build.xml ]]; then + echo 'Ant build.xml file not found! Check that you are in the right directory.' + exit 9 +fi + +# Copy base classes from wlauto dist +class_dir=bin/classes/com/arm/wlauto/uiauto +base_classes=`python -c "import os, wlauto; print os.path.join(os.path.dirname(wlauto.__file__), 'common', 'android', '*.class')"` +mkdir -p $class_dir +cp $base_classes $class_dir + +# Build and return appropriate exit code if failed +ant build +exit_code=$? +if [[ $exit_code -ne 0 ]]; then + echo "ERROR: 'ant build' exited with code $exit_code" + exit $exit_code +fi + +# If successful move JAR file to workload folder (overwrite previous) +package=com.arm.wlauto.uiauto.youtube.jar +rm -f ../$package +if [[ -f bin/$package ]]; then + cp bin/$package .. +else + echo 'ERROR: UiAutomator JAR could not be found!' + exit 9 +fi diff --git a/wlauto/workloads/youtube/uiauto/build.xml b/wlauto/workloads/youtube/uiauto/build.xml new file mode 100644 index 00000000..b0e91680 --- /dev/null +++ b/wlauto/workloads/youtube/uiauto/build.xml @@ -0,0 +1,92 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/wlauto/workloads/youtube/uiauto/project.properties b/wlauto/workloads/youtube/uiauto/project.properties new file mode 100644 index 00000000..ce39f2d0 --- /dev/null +++ b/wlauto/workloads/youtube/uiauto/project.properties @@ -0,0 +1,14 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must be checked in Version Control Systems. +# +# To customize properties used by the Ant build system edit +# "ant.properties", and override values to adapt the script to your +# project structure. +# +# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): +#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt + +# Project target. +target=android-18 diff --git a/wlauto/workloads/youtube/uiauto/src/com/arm/wlauto/uiauto/UiAutomation.java b/wlauto/workloads/youtube/uiauto/src/com/arm/wlauto/uiauto/UiAutomation.java new file mode 100644 index 00000000..339bd0bf --- /dev/null +++ b/wlauto/workloads/youtube/uiauto/src/com/arm/wlauto/uiauto/UiAutomation.java @@ -0,0 +1,239 @@ +/* Copyright 2014-2016 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.arm.wlauto.uiauto.youtube; + +import android.os.Bundle; +import android.os.SystemClock; +import android.util.Log; + +// Import the uiautomator libraries +import com.android.uiautomator.core.UiObject; +import com.android.uiautomator.core.UiScrollable; +import com.android.uiautomator.core.UiSelector; + +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; + +public class UiAutomation extends UxPerfUiAutomation { + + public static final String CLASS_BUTTON = "android.widget.Button"; + public static final String CLASS_TEXT_VIEW = "android.widget.TextView"; + + public static final int WAIT_TIMEOUT_1SEC = 1000; + public static final int WAIT_TIMEOUT_5SEC = 5000; + public static final int VIDEO_SLEEP_SECONDS = 3; + public static final int LIST_SWIPE_COUNT = 5; + public static final String SOURCE_MY_VIDEOS = "my_videos"; + public static final String SOURCE_SEARCH = "search"; + public static final String SOURCE_TRENDING = "trending"; + + protected ActionLogger logger; + protected Bundle parameters; + protected String packageName; + protected String packageID; + protected String searchTerm; + + public void runUiAutomation() throws Exception { + parameters = getParams(); + packageName = parameters.getString("package"); + packageID = packageName + ":id/"; + searchTerm = parameters.getString("search_term"); + if (searchTerm != null) { + searchTerm = searchTerm.replaceAll("0space0", " "); + } + + setScreenOrientation(ScreenOrientation.NATURAL); + clearFirstRunDialogues(); + disableAutoplay(); + testPlayVideo(parameters.getString("video_source"), searchTerm); + unsetScreenOrientation(); + } + + public void clearFirstRunDialogues() throws Exception { + UiObject laterButton = new UiObject(new UiSelector().textContains("Later").className(CLASS_TEXT_VIEW)); + if (laterButton.waitForExists(WAIT_TIMEOUT_1SEC)) { + laterButton.click(); + } + UiObject cancelButton = new UiObject(new UiSelector().textContains("Cancel").className(CLASS_BUTTON)); + if (cancelButton.waitForExists(WAIT_TIMEOUT_1SEC)) { + cancelButton.click(); + } + UiObject skipButton = new UiObject(new UiSelector().textContains("Skip").className(CLASS_TEXT_VIEW)); + if (skipButton.waitForExists(WAIT_TIMEOUT_1SEC)) { + skipButton.click(); + } + UiObject gotItButton = new UiObject(new UiSelector().textContains("Got it").className(CLASS_BUTTON)); + if (gotItButton.waitForExists(WAIT_TIMEOUT_1SEC)) { + gotItButton.click(); + } + } + + public void disableAutoplay() throws Exception { + clickUiObject(BY_DESC, "More options"); + startMeasurements("goto_settings"); + clickUiObject(BY_TEXT, "Settings", true); + endMeasurements("goto_settings"); + startMeasurements("goto_settings_general"); + clickUiObject(BY_TEXT, "General", true); + endMeasurements("goto_settings_general"); + + // Don't fail fatally if autoplay toggle cannot be found + UiObject autoplayToggle = new UiObject(new UiSelector().textContains("Autoplay")); + if (autoplayToggle.waitForExists(WAIT_TIMEOUT_1SEC)) { + autoplayToggle.click(); + } + getUiDevice().pressBack(); + + // Tablet devices use a split with General in the left pane and Autoplay in the right so no + // need to click back twice + UiObject generalButton = new UiObject(new UiSelector().textContains("General").className(CLASS_TEXT_VIEW)); + if (generalButton.exists()) { + getUiDevice().pressBack(); + } + } + + public void testPlayVideo(String source, String searchTerm) throws Exception { + if (SOURCE_MY_VIDEOS.equalsIgnoreCase(source)) { + startMeasurements("goto_account"); + clickUiObject(BY_DESC, "Account"); + endMeasurements("goto_account"); + startMeasurements("goto_my_videos"); + clickUiObject(BY_TEXT, "My Videos", true); + endMeasurements("goto_my_videos"); + + startMeasurements("play_from_my_videos"); + clickUiObject(BY_ID, packageID + "thumbnail", true); + endMeasurements("play_from_my_videos"); + + } else if (SOURCE_SEARCH.equalsIgnoreCase(source)) { + startMeasurements("goto_search"); + clickUiObject(BY_DESC, "Search"); + endMeasurements("goto_search"); + + startMeasurements("search_video"); + UiObject textField = getUiObjectByResourceId(packageID + "search_edit_text"); + textField.setText(searchTerm); + endMeasurements("search_video"); + + getUiDevice().pressEnter(); + startMeasurements("play_from_search"); + // If a video exists whose title contains the exact search term, then play it + // Otherwise click the first video in the search results + UiObject thumbnail = new UiObject(new UiSelector().resourceId(packageID + "thumbnail")); + UiObject matchedVideo = thumbnail.getFromParent(new UiSelector().textContains(searchTerm)); + if (matchedVideo.exists()) { + matchedVideo.clickAndWaitForNewWindow(); + } else { + thumbnail.clickAndWaitForNewWindow(); + } + endMeasurements("play_from_search"); + + } else if (SOURCE_TRENDING.equalsIgnoreCase(source)) { + startMeasurements("goto_trending"); + clickUiObject(BY_DESC, "Trending"); + endMeasurements("goto_trending"); + + startMeasurements("play_from_trending"); + clickUiObject(BY_ID, packageID + "thumbnail", true); + endMeasurements("play_from_trending"); + + } else { // homepage videos + UiScrollable list = new UiScrollable(new UiSelector().resourceId(packageID + "results")); + if (list.exists()) { + list.scrollForward(); + } + startMeasurements("play_from_home"); + clickUiObject(BY_ID, packageID + "thumbnail", true); + endMeasurements("play_from_home"); + } + + dismissAdvert(); + checkPlayerError(); + pausePlayVideo(); + checkVideoInfo(); + scrollRelated(); + } + + public void dismissAdvert() throws Exception { + UiObject advert = new UiObject(new UiSelector().textContains("Visit advertiser")); + if (advert.exists()) { + UiObject skip = new UiObject(new UiSelector().textContains("Skip ad")); + if (skip.waitForExists(WAIT_TIMEOUT_5SEC)) { + skip.click(); + sleep(VIDEO_SLEEP_SECONDS); + } + } + } + + public void checkPlayerError() throws Exception { + UiObject playerError = new UiObject(new UiSelector().resourceId(packageID + "player_error_view")); + UiObject tapToRetry = new UiObject(new UiSelector().textContains("Tap to retry")); + if (playerError.waitForExists(WAIT_TIMEOUT_1SEC) || tapToRetry.waitForExists(WAIT_TIMEOUT_1SEC)) { + throw new RuntimeException("Video player encountered an error and cannot continue."); + } + } + + public void pausePlayVideo() throws Exception { + UiObject player = getUiObjectByResourceId(packageID + "player_fragment_container"); + sleep(VIDEO_SLEEP_SECONDS); + repeatClickUiObject(player, 2, 100); + sleep(1); // pause the video momentarily + player.click(); + startMeasurements("player_video_windowed"); + sleep(VIDEO_SLEEP_SECONDS); + endMeasurements("player_video_windowed"); + } + + public void checkVideoInfo() throws Exception { + UiObject expandButton = new UiObject(new UiSelector().resourceId(packageID + "expand_button")); + if (!expandButton.waitForExists(WAIT_TIMEOUT_1SEC)) { + return; + } + // Expand video info + expandButton.click(); + SystemClock.sleep(500); // short delay to simulate user action + expandButton.click(); + } + + public void scrollRelated() throws Exception { + // ListView of related videos and (maybe) comments + UiScrollable list = new UiScrollable(new UiSelector().resourceId(packageID + "watch_list")); + if (list.isScrollable()) { + startMeasurements("watch_list_fling_down"); + list.flingToEnd(LIST_SWIPE_COUNT); + endMeasurements("watch_list_fling_down"); + + startMeasurements("watch_list_fling_up"); + list.flingToBeginning(LIST_SWIPE_COUNT); + endMeasurements("watch_list_fling_up"); + } + // After flinging, give the window enough time to settle down before + // the next step, or else UiAutomator fails to find views in time + sleep(VIDEO_SLEEP_SECONDS); + } + + protected void startMeasurements(String testTag) throws Exception { + logger = new ActionLogger(testTag, parameters); + logger.start(); + } + + protected void endMeasurements(String testTag) throws Exception { + logger.stop(); + } +}