1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.tv.tests.ui.dvr; 18 19 import static com.android.tv.testing.uihelper.UiDeviceAsserts.assertWaitUntilFocused; 20 21 import android.os.Build; 22 import android.support.test.filters.MediumTest; 23 import android.support.test.filters.SdkSuppress; 24 import android.support.test.uiautomator.By; 25 import android.support.test.uiautomator.BySelector; 26 import android.support.test.uiautomator.Until; 27 import com.android.tv.R; 28 import com.android.tv.testing.uihelper.ByResource; 29 import com.android.tv.testing.uihelper.Constants; 30 import com.android.tv.tests.ui.LiveChannelsTestController; 31 import java.util.regex.Pattern; 32 import org.junit.Before; 33 import org.junit.Ignore; 34 import org.junit.Rule; 35 import org.junit.Test; 36 import org.junit.runner.RunWith; 37 import org.junit.runners.JUnit4; 38 39 /** Test the DVR library UI */ 40 @MediumTest 41 @RunWith(JUnit4.class) 42 @SdkSuppress(minSdkVersion = Build.VERSION_CODES.N) 43 public class DvrLibraryTest { 44 private static final String PROGRAM_NAME_PREFIX = "Title("; 45 46 @Rule public final LiveChannelsTestController controller = new LiveChannelsTestController(); 47 48 private BySelector mRecentRow; 49 private BySelector mScheduledRow; 50 private BySelector mSeriesRow; 51 private BySelector mFullScheduleCard; 52 53 @Before 54 public void setUp() throws Exception { 55 56 mRecentRow = 57 By.hasDescendant( 58 ByResource.text(controller.getTargetResources(), R.string.dvr_main_recent)); 59 mScheduledRow = 60 By.hasDescendant( 61 ByResource.text( 62 controller.getTargetResources(), R.string.dvr_main_scheduled)); 63 mSeriesRow = 64 By.hasDescendant( 65 ByResource.text(controller.getTargetResources(), R.string.dvr_main_series)); 66 mFullScheduleCard = 67 By.focusable(true) 68 .hasDescendant( 69 ByResource.text( 70 controller.getTargetResources(), 71 R.string.dvr_full_schedule_card_view_title)); 72 controller.liveChannelsHelper.assertAppStarted(); 73 } 74 75 @Test 76 public void placeholder() { 77 // TODO(b/72153742): three must be at least one test 78 } 79 80 @Ignore("b/72153742") 81 @Test 82 public void testCancel() { 83 controller.menuHelper.assertPressDvrLibrary(); 84 controller.assertWaitForCondition(Until.hasObject(Constants.DVR_LIBRARY)); 85 controller.pressBack(); 86 controller.assertWaitForCondition(Until.gone(Constants.DVR_LIBRARY)); 87 controller.assertHas(Constants.MENU, false); 88 } 89 90 @Ignore("b/72153742") 91 @Test 92 public void testEmptyLibrary() { 93 controller.menuHelper.assertPressDvrLibrary(); 94 controller.assertWaitForCondition(Until.hasObject(Constants.DVR_LIBRARY)); 95 96 // DVR Library is empty, only Scheduled row and Full schedule card should be displayed. 97 controller.assertHas(mRecentRow, false); 98 controller.assertHas(mScheduledRow, true); 99 controller.assertHas(mSeriesRow, false); 100 101 controller.pressDPadCenter(); 102 assertWaitUntilFocused(controller.getUiDevice(), mFullScheduleCard); 103 controller.pressDPadCenter(); 104 controller.assertWaitForCondition(Until.gone(Constants.DVR_LIBRARY)); 105 106 // Empty schedules screen should be shown. 107 controller.assertHas(Constants.DVR_SCHEDULES, true); 108 controller.assertHas( 109 ByResource.text( 110 controller.getTargetResources(), R.string.dvr_schedules_empty_state), 111 true); 112 113 // Close the DVR library. 114 controller.pressBack(); 115 controller.assertWaitForCondition(Until.hasObject(Constants.DVR_LIBRARY)); 116 controller.pressBack(); 117 controller.assertWaitForCondition(Until.gone(Constants.DVR_LIBRARY)); 118 } 119 120 @Ignore("b/72153742") 121 @Test 122 public void testScheduleRecordings() { 123 BySelector newScheduleCard = 124 By.focusable(true) 125 .hasDescendant(By.textStartsWith(PROGRAM_NAME_PREFIX)) 126 .hasDescendant(By.textEndsWith("today")); 127 BySelector seriesCardWithOneSchedule = 128 By.focusable(true) 129 .hasDescendant(By.textStartsWith(PROGRAM_NAME_PREFIX)) 130 .hasDescendant( 131 By.text( 132 controller 133 .getTargetResources() 134 .getQuantityString( 135 R.plurals.dvr_count_scheduled_recordings, 136 1, 137 1))); 138 BySelector seriesCardWithOneRecordedProgram = 139 By.focusable(true) 140 .hasDescendant(By.textStartsWith(PROGRAM_NAME_PREFIX)) 141 .hasDescendant( 142 By.text( 143 controller 144 .getTargetResources() 145 .getQuantityString( 146 R.plurals.dvr_count_new_recordings, 1, 1))); 147 Pattern watchButton = 148 Pattern.compile( 149 "^" 150 + controller 151 .getTargetResources() 152 .getString(R.string.dvr_detail_watch) 153 .toUpperCase() 154 + "\n.*$"); 155 156 controller.menuHelper.showMenu(); 157 controller.menuHelper.assertNavigateToPlayControlsRow(); 158 controller.pressDPadRight(); 159 controller.pressDPadCenter(); 160 controller.assertWaitForCondition( 161 Until.hasObject( 162 ByResource.text( 163 controller.getTargetResources(), 164 R.string.dvr_action_record_episode))); 165 controller.pressDPadCenter(); 166 controller.assertWaitForCondition( 167 Until.gone( 168 ByResource.text( 169 controller.getTargetResources(), 170 R.string.dvr_action_record_episode))); 171 172 controller.menuHelper.assertPressDvrLibrary(); 173 controller.assertWaitForCondition(Until.hasObject(Constants.DVR_LIBRARY)); 174 175 // Schedule should be automatically added to the series. 176 controller.assertHas(mRecentRow, false); 177 controller.assertHas(mScheduledRow, true); 178 controller.assertHas(mSeriesRow, true); 179 String programName = 180 controller 181 .getUiDevice() 182 .findObject(By.textStartsWith(PROGRAM_NAME_PREFIX)) 183 .getText(); 184 185 // Move to scheduled row, there should be one new schedule and one full schedule card. 186 controller.pressDPadRight(); 187 controller.assertWaitUntilFocused(newScheduleCard); 188 controller.pressDPadRight(); 189 controller.assertWaitUntilFocused(mFullScheduleCard); 190 191 // Enters the full schedule, there should be one schedule in the full schedule. 192 controller.pressDPadCenter(); 193 controller.assertWaitForCondition(Until.gone(Constants.DVR_LIBRARY)); 194 controller.assertHas(Constants.DVR_SCHEDULES, true); 195 controller.assertHas( 196 ByResource.text( 197 controller.getTargetResources(), R.string.dvr_schedules_empty_state), 198 false); 199 controller.assertHas(By.textStartsWith(programName), true); 200 201 // Moves to the series card, clicks it, the detail page should be shown with "View schedule" 202 // button. 203 controller.pressBack(); 204 controller.assertWaitForCondition(Until.hasObject(Constants.DVR_LIBRARY)); 205 controller.pressDPadLeft(); 206 controller.assertWaitUntilFocused(newScheduleCard); 207 controller.pressDPadDown(); 208 controller.assertWaitUntilFocused(seriesCardWithOneSchedule); 209 controller.pressDPadCenter(); 210 controller.assertWaitForCondition(Until.gone(Constants.DVR_LIBRARY)); 211 controller.assertHas( 212 By.text( 213 controller 214 .getTargetResources() 215 .getString(R.string.dvr_detail_view_schedule) 216 .toUpperCase()), 217 true); 218 controller.assertHas(By.text(watchButton), false); 219 controller.assertHas( 220 By.text( 221 controller 222 .getTargetResources() 223 .getString(R.string.dvr_detail_series_delete) 224 .toUpperCase()), 225 false); 226 227 // Clicks the new schedule, the detail page should be shown with "Stop recording" button. 228 controller.pressBack(); 229 controller.assertWaitForCondition(Until.hasObject(Constants.DVR_LIBRARY)); 230 controller.assertWaitUntilFocused(seriesCardWithOneSchedule); 231 controller.pressDPadUp(); 232 controller.assertWaitUntilFocused(newScheduleCard); 233 controller.pressDPadCenter(); 234 controller.assertWaitForCondition(Until.gone(Constants.DVR_LIBRARY)); 235 controller.assertHas( 236 By.text( 237 controller 238 .getTargetResources() 239 .getString(R.string.dvr_detail_stop_recording) 240 .toUpperCase()), 241 true); 242 243 // Stops the recording 244 controller.pressDPadCenter(); 245 controller.assertWaitForCondition( 246 Until.hasObject( 247 ByResource.text( 248 controller.getTargetResources(), R.string.dvr_action_stop))); 249 controller.pressDPadCenter(); 250 controller.assertWaitForCondition( 251 Until.gone( 252 ByResource.text( 253 controller.getTargetResources(), R.string.dvr_action_stop))); 254 controller.assertWaitForCondition(Until.hasObject(Constants.DVR_LIBRARY)); 255 controller.assertWaitUntilFocused(mFullScheduleCard); 256 257 // Moves to series' detail page again, now it should have two more buttons 258 controller.pressDPadDown(); 259 controller.assertWaitUntilFocused(seriesCardWithOneRecordedProgram); 260 controller.pressDPadCenter(); 261 controller.assertWaitForCondition(Until.gone(Constants.DVR_LIBRARY)); 262 controller.assertHas(By.text(watchButton), true); 263 controller.assertHas( 264 By.text( 265 controller 266 .getTargetResources() 267 .getString(R.string.dvr_detail_view_schedule) 268 .toUpperCase()), 269 true); 270 controller.assertHas( 271 By.text( 272 controller 273 .getTargetResources() 274 .getString(R.string.dvr_detail_series_delete) 275 .toUpperCase()), 276 true); 277 278 // Moves to the recent row and clicks the recent recorded program. 279 controller.pressBack(); 280 controller.assertWaitForCondition(Until.hasObject(Constants.DVR_LIBRARY)); 281 controller.assertWaitUntilFocused(seriesCardWithOneRecordedProgram); 282 controller.pressDPadUp(); 283 controller.assertWaitUntilFocused(mFullScheduleCard); 284 controller.pressDPadUp(); 285 controller.assertWaitUntilFocused(By.focusable(true).hasDescendant(By.text(programName))); 286 controller.pressDPadCenter(); 287 controller.assertWaitForCondition(Until.gone(Constants.DVR_LIBRARY)); 288 controller.assertHas( 289 By.text( 290 controller 291 .getTargetResources() 292 .getString(R.string.dvr_detail_watch) 293 .toUpperCase()), 294 true); 295 controller.assertHas( 296 By.text( 297 controller 298 .getTargetResources() 299 .getString(R.string.dvr_detail_delete) 300 .toUpperCase()), 301 true); 302 303 // Moves to the delete button and clicks to remove the recorded program. 304 controller.pressDPadRight(); 305 controller.assertWaitUntilFocused( 306 By.text( 307 controller 308 .getTargetResources() 309 .getString(R.string.dvr_detail_delete) 310 .toUpperCase())); 311 controller.pressDPadCenter(); 312 controller.assertWaitForCondition(Until.hasObject(Constants.DVR_LIBRARY)); 313 controller.assertWaitUntilFocused(mFullScheduleCard); 314 315 // DVR Library should be empty now. 316 controller.assertHas(mRecentRow, false); 317 controller.assertHas(mScheduledRow, true); 318 controller.assertHas(mSeriesRow, false); 319 320 // Close the DVR library. 321 controller.pressBack(); 322 controller.assertWaitForCondition(Until.gone(Constants.DVR_LIBRARY)); 323 } 324 } 325