1/* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 * in compliance with the License. You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software distributed under the License 10 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 * or implied. See the License for the specific language governing permissions and limitations under 12 * the License. 13 */ 14 15package android.support.v17.leanback.app.wizard; 16 17import static org.junit.Assert.assertTrue; 18 19import android.content.Context; 20import android.content.Intent; 21import android.content.res.Resources; 22import android.support.test.InstrumentationRegistry; 23import android.support.test.filters.LargeTest; 24import android.support.test.rule.ActivityTestRule; 25import android.support.test.runner.AndroidJUnit4; 26import android.support.v17.leanback.app.GuidedStepFragment; 27import android.support.v17.leanback.test.R; 28import android.support.v17.leanback.widget.GuidanceStylist; 29import android.support.v17.leanback.widget.GuidedAction; 30import android.support.v17.leanback.widget.GuidedDatePickerAction; 31import android.support.v17.leanback.widget.VerticalGridView; 32import android.support.v17.leanback.widget.picker.DatePicker; 33import android.util.Log; 34import android.view.KeyEvent; 35import android.widget.LinearLayout; 36 37import org.junit.Before; 38import org.junit.Rule; 39import org.junit.Test; 40import org.junit.runner.RunWith; 41 42import java.text.SimpleDateFormat; 43import java.util.ArrayList; 44import java.util.Calendar; 45import java.util.Date; 46import java.util.List; 47 48@LargeTest 49@RunWith(AndroidJUnit4.class) 50public class GuidedDatePickerTest { 51 52 static final long TRANSITION_LENGTH = 1000; 53 static long VERTICAL_SCROLL_WAIT = 500; 54 static long HORIZONTAL_SCROLL_WAIT = 500; 55 static final long FINAL_WAIT = 1000; 56 57 static final String TAG = "GuidedDatePickerTest"; 58 59 private static final int DAY_INDEX = 0; 60 private static final int MONTH_INDEX = 1; 61 private static final int YEAR_INDEX = 2; 62 63 @Rule 64 public ActivityTestRule<GuidedStepAttributesTestActivity> activityTestRule = 65 new ActivityTestRule<>(GuidedStepAttributesTestActivity.class, false, false); 66 67 GuidedStepAttributesTestActivity mActivity; 68 69 70 private void initActivity(Intent intent) { 71 mActivity = activityTestRule.launchActivity(intent); 72 try { 73 Thread.sleep(2000); 74 } catch(InterruptedException e) { 75 e.printStackTrace(); 76 } 77 78 } 79 80 Context mContext; 81 @Before 82 public void setUp() { 83 mContext = InstrumentationRegistry.getInstrumentation().getTargetContext();; 84 } 85 86 public static void sendKey(int keyCode) { 87 InstrumentationRegistry.getInstrumentation().sendKeyDownUpSync(keyCode); 88 } 89 90 private int getColumnIndexForDateField(int field, int[] columnIndices) { 91 int mColDayIndex = columnIndices[0]; 92 int mColMonthIndex = columnIndices[1]; 93 int mColYearIndex = columnIndices[2]; 94 int columnIndex = -1; 95 switch (field) { 96 case Calendar.DAY_OF_MONTH: 97 columnIndex = mColDayIndex; 98 break; 99 case Calendar.MONTH: 100 columnIndex = mColMonthIndex; 101 break; 102 case Calendar.YEAR: 103 columnIndex = mColYearIndex; 104 } 105 return columnIndex; 106 } 107 108 private void horizontalScrollToDateField(int field, int[] columnIndices, 109 DatePicker pickerView) throws Throwable{ 110 int columnIndex = getColumnIndexForDateField(field, columnIndices); 111 112 LinearLayout columnsLayout = (LinearLayout) pickerView.getChildAt(0); 113 114 int focusedFieldPos = columnsLayout.indexOfChild(columnsLayout.getFocusedChild()); 115 if (focusedFieldPos == -1) { 116 sendKey(KeyEvent.KEYCODE_DPAD_CENTER); 117 Thread.sleep(TRANSITION_LENGTH); 118 } 119 focusedFieldPos = columnsLayout.indexOfChild(columnsLayout.getFocusedChild()); 120 assertTrue("Date field could not be focused!", (focusedFieldPos != -1)); 121 122 // following is to skip the separator fields "/" which are unfocusable but counted as 123 // children of columnsLayout 124 switch (focusedFieldPos) { 125 case 0: 126 focusedFieldPos = 0; 127 break; 128 case 2: 129 focusedFieldPos = 1; 130 break; 131 case 4: 132 focusedFieldPos = 2; 133 } 134 135 // now scroll right or left to the corresponding date field as indicated by the input field 136 int horizontalScrollOffset = columnIndex - focusedFieldPos; 137 138 int horizontalScrollDir = KeyEvent.KEYCODE_DPAD_RIGHT; 139 if (horizontalScrollOffset < 0) { 140 horizontalScrollOffset = -horizontalScrollOffset; 141 horizontalScrollDir = KeyEvent.KEYCODE_DPAD_LEFT; 142 } 143 for(int i = 0; i < horizontalScrollOffset; i++) { 144 sendKey(horizontalScrollDir); 145 Thread.sleep(HORIZONTAL_SCROLL_WAIT); 146 } 147 148 } 149 150 /** 151 * Scrolls vertically all the way up or down (depending on the provided scrollDir parameter) 152 * to fieldValue if it's not equal to -1; otherwise, the scrolling goes all the way to the end. 153 * @param field The date field over which the scrolling is performed 154 * @param fieldValue The field value to scroll to or -1 if the scrolling should go all the way. 155 * @param columnIndices The date field indices corresponding to day, month, and the year 156 * @param pickerView The DatePicker view. 157 * @param scrollDir The direction of scrolling to reach the desired field value. 158 * @throws Throwable 159 */ 160 private void verticalScrollToFieldValue(int field, int fieldValue, int[] columnIndices, 161 DatePicker pickerView, int scrollDir) 162 throws Throwable { 163 164 int columnIndex = getColumnIndexForDateField(field, columnIndices); 165 int colDayIndex = columnIndices[0]; 166 int colMonthIndex = columnIndices[1]; 167 int colYearIndex = columnIndices[2]; 168 169 horizontalScrollToDateField(field, columnIndices, pickerView); 170 171 Calendar currentActionCal = Calendar.getInstance(); 172 currentActionCal.setTimeInMillis(pickerView.getDate()); 173 174 Calendar minCal = Calendar.getInstance(); 175 minCal.setTimeInMillis(pickerView.getMinDate()); 176 177 Calendar maxCal = Calendar.getInstance(); 178 maxCal.setTimeInMillis(pickerView.getMaxDate()); 179 180 181 int prevColumnVal = -1; 182 int currentColumnVal = pickerView.getColumnAt(columnIndex).getCurrentValue(); 183 while( currentColumnVal != prevColumnVal && currentColumnVal != fieldValue){ 184 assertTrue(mContext.getString(R.string.datepicker_test_wrong_day_value), 185 pickerView.getColumnAt(colDayIndex).getCurrentValue() 186 == currentActionCal.get(Calendar.DAY_OF_MONTH) 187 ); 188 assertTrue(mContext.getString(R.string.datepicker_test_wrong_month_value), 189 pickerView.getColumnAt(colMonthIndex).getCurrentValue() 190 == currentActionCal.get(Calendar.MONTH) 191 ); 192 assertTrue(mContext.getString(R.string.datepicker_test_wrong_year_value), 193 pickerView.getColumnAt(colYearIndex).getCurrentValue() 194 == currentActionCal.get(Calendar.YEAR) 195 ); 196 197 int offset = scrollDir == KeyEvent.KEYCODE_DPAD_DOWN ? 1 : -1; 198 addDate(currentActionCal, field, offset, minCal, maxCal); 199 200 sendKey(scrollDir); 201 Thread.sleep(VERTICAL_SCROLL_WAIT); 202 203 prevColumnVal = currentColumnVal; 204 currentColumnVal = pickerView.getColumnAt(columnIndex).getCurrentValue(); 205 } 206 } 207 208 private void addDate(Calendar mCurrentDate, int field, int offset, 209 Calendar mMinDate, Calendar mMaxDate) { 210 int maxOffset = -1; 211 int actualMinFieldValue, actualMaxFieldValue; 212 213 if ( field == Calendar.YEAR ) { 214 actualMinFieldValue = mMinDate.get(Calendar.YEAR); 215 actualMaxFieldValue = mMaxDate.get(Calendar.YEAR); 216 } else { 217 actualMinFieldValue = mCurrentDate.getActualMinimum(field); 218 actualMaxFieldValue = mCurrentDate.getActualMaximum(field); 219 } 220 221 if ( offset > 0 ) { 222 maxOffset = Math.min( 223 actualMaxFieldValue - mCurrentDate.get(field), offset); 224 mCurrentDate.add(field, maxOffset); 225 if (mCurrentDate.after(mMaxDate)) { 226 mCurrentDate.setTimeInMillis(mMaxDate.getTimeInMillis()); 227 } 228 } else { 229 maxOffset = Math.max( 230 actualMinFieldValue - mCurrentDate.get(field), offset); 231 mCurrentDate.add(field, Math.max(offset, maxOffset)); 232 if (mCurrentDate.before(mMinDate)) { 233 mCurrentDate.setTimeInMillis(mMinDate.getTimeInMillis()); 234 } 235 } 236 } 237 238 @Test 239 public void testJanuaryToFebruaryTransitionForLeapYear() throws Throwable { 240 long startTime = System.currentTimeMillis(); 241 Intent intent = new Intent(); 242 243 String title = "Date Picker Transition Test"; 244 String breadcrumb = "Month Transition Test Demo"; 245 String description = "Testing the transition from Jan to Feb (leap year)"; 246 GuidanceStylist.Guidance guidance = new GuidanceStylist.Guidance(title, description, 247 breadcrumb, null); 248 249 List<GuidedAction> actionList = new ArrayList<>(); 250 251 Calendar cal = Calendar.getInstance(); 252 253 cal.set(Calendar.YEAR, 2016); // 2016 is a leap year 254 cal.set(Calendar.MONTH, Calendar.JANUARY); 255 cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH)); 256 Date initialDate = cal.getTime(); 257 258 GuidedDatePickerAction action = new GuidedDatePickerAction.Builder( 259 mContext) 260 .id(0) 261 .title("Date") 262 .date(initialDate.getTime()) 263 .datePickerFormat("DMY") 264 .build(); 265 266 actionList.add(action); 267 268 GuidedStepAttributesTestFragment.clear(); 269 GuidedStepAttributesTestFragment.GUIDANCE = guidance; 270 GuidedStepAttributesTestFragment.ACTION_LIST = actionList; 271 272 initActivity(intent); 273 274 DatePicker mPickerView = (DatePicker) mActivity.findViewById( 275 R.id.guidedactions_activator_item); 276 277 verticalScrollToFieldValue(Calendar.MONTH, Calendar.FEBRUARY, new int[] {0, 1, 2}, 278 mPickerView, KeyEvent.KEYCODE_DPAD_DOWN); 279 long executionTime = System.currentTimeMillis() - startTime; 280 Log.d(TAG, "testJanuaryToFebruaryTransitionForLeapYear() Execution time: " + executionTime); 281 Thread.sleep(FINAL_WAIT); 282 } 283 284 @Test 285 public void testFebruaryToMarchTransitionForLeapYear() throws Throwable { 286 long startTime = System.currentTimeMillis(); 287 Intent intent = new Intent(); 288 289 String title = "Date Picker Transition Test"; 290 String breadcrumb = "Month Transition Test Demo"; 291 String description = "Testing the transition from Feb to Mar (leap year)"; 292 GuidanceStylist.Guidance guidance = new GuidanceStylist.Guidance(title, description, 293 breadcrumb, null); 294 295 List<GuidedAction> actionList = new ArrayList<>(); 296 297 Calendar cal = Calendar.getInstance(); 298 299 cal.set(Calendar.YEAR, 2016); 300 cal.set(Calendar.MONTH, Calendar.FEBRUARY); 301 cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH)); 302 Date initialDate = cal.getTime(); 303 304 GuidedDatePickerAction action = new GuidedDatePickerAction.Builder( 305 mContext) 306 .id(0) 307 .title("Date") 308 .date(initialDate.getTime()) 309 .datePickerFormat("DMY") 310 .build(); 311 312 actionList.add(action); 313 314 GuidedStepAttributesTestFragment.clear(); 315 GuidedStepAttributesTestFragment.GUIDANCE = guidance; 316 GuidedStepAttributesTestFragment.ACTION_LIST = actionList; 317 318 initActivity(intent); 319 320 DatePicker mPickerView = (DatePicker) mActivity.findViewById( 321 R.id.guidedactions_activator_item); 322 323 verticalScrollToFieldValue(Calendar.MONTH, Calendar.MARCH, new int[] {0, 1, 2}, 324 mPickerView, KeyEvent.KEYCODE_DPAD_DOWN); 325 long executionTime = System.currentTimeMillis() - startTime; 326 Log.d(TAG, "testFebruaryToMarchTransition() Execution time: " + executionTime); 327 Thread.sleep(FINAL_WAIT); 328 } 329 330 @Test 331 public void testJanuaryToFebruaryTransitionForNonLeapYear() throws Throwable { 332 long startTime = System.currentTimeMillis(); 333 Intent intent = new Intent(); 334 335 String title = "Date Picker Transition Test"; 336 String breadcrumb = "Month Transition Test Demo"; 337 String description = "Testing the transition from Jan to Feb (nonleap year)"; 338 GuidanceStylist.Guidance guidance = new GuidanceStylist.Guidance(title, description, 339 breadcrumb, null); 340 341 List<GuidedAction> actionList = new ArrayList<>(); 342 343 Calendar cal = Calendar.getInstance(); 344 345 cal.set(Calendar.YEAR, 2017); // 2017 is a leap year 346 cal.set(Calendar.MONTH, Calendar.JANUARY); 347 cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH)); 348 Date initialDate = cal.getTime(); 349 350 GuidedDatePickerAction action = new GuidedDatePickerAction.Builder( 351 mContext) 352 .id(0) 353 .title("Date") 354 .date(initialDate.getTime()) 355 .datePickerFormat("DMY") 356 .build(); 357 358 actionList.add(action); 359 360 GuidedStepAttributesTestFragment.clear(); 361 GuidedStepAttributesTestFragment.GUIDANCE = guidance; 362 GuidedStepAttributesTestFragment.ACTION_LIST = actionList; 363 364 initActivity(intent); 365 366 DatePicker mPickerView = (DatePicker) mActivity.findViewById( 367 R.id.guidedactions_activator_item); 368 369 verticalScrollToFieldValue(Calendar.MONTH, Calendar.FEBRUARY, new int[] {0, 1, 2}, 370 mPickerView, KeyEvent.KEYCODE_DPAD_DOWN); 371 long executionTime = System.currentTimeMillis() - startTime; 372 Log.d(TAG, "testJanuaryToFebruaryTransition() Execution time: " + executionTime); 373 Thread.sleep(FINAL_WAIT); 374 } 375 376 @Test 377 public void testFebruaryToMarchTransitionForNonLeapYear() throws Throwable { 378 long startTime = System.currentTimeMillis(); 379 Intent intent = new Intent(); 380 381 String title = "Date Picker Transition Test"; 382 String breadcrumb = "Month Transition Test Demo"; 383 String description = "Testing the transition from Feb to Mar (nonleap year)"; 384 GuidanceStylist.Guidance guidance = new GuidanceStylist.Guidance(title, description, 385 breadcrumb, null); 386 387 List<GuidedAction> actionList = new ArrayList<>(); 388 389 Calendar cal = Calendar.getInstance(); 390 391 cal.set(Calendar.YEAR, 2017); 392 cal.set(Calendar.MONTH, Calendar.FEBRUARY); 393 cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH)); 394 Date initialDate = cal.getTime(); 395 396 GuidedDatePickerAction action = new GuidedDatePickerAction.Builder( 397 mContext) 398 .id(0) 399 .title("Date") 400 .date(initialDate.getTime()) 401 .datePickerFormat("DMY") 402 .build(); 403 404 actionList.add(action); 405 406 GuidedStepAttributesTestFragment.clear(); 407 GuidedStepAttributesTestFragment.GUIDANCE = guidance; 408 GuidedStepAttributesTestFragment.ACTION_LIST = actionList; 409 410 initActivity(intent); 411 412 DatePicker mPickerView = (DatePicker) mActivity.findViewById( 413 R.id.guidedactions_activator_item); 414 415 verticalScrollToFieldValue(Calendar.MONTH, Calendar.MARCH, new int[] {0, 1, 2}, 416 mPickerView, KeyEvent.KEYCODE_DPAD_DOWN); 417 long executionTime = System.currentTimeMillis() - startTime; 418 Log.d(TAG, "testFebruaryToMarchTransition() Execution time: " + executionTime); 419 Thread.sleep(FINAL_WAIT); 420 } 421 422 @Test 423 public void testDecemberToNovemberTransition() throws Throwable { 424 long startTime = System.currentTimeMillis(); 425 Intent intent = new Intent(); 426 427 String title = "Date Picker Transition Test"; 428 String breadcrumb = "Month Transition Test Demo"; 429 String description = "Testing the transition from Dec to Nov"; 430 GuidanceStylist.Guidance guidance = new GuidanceStylist.Guidance(title, description, 431 breadcrumb, null); 432 433 List<GuidedAction> actionList = new ArrayList<>(); 434 435 Calendar cal = Calendar.getInstance(); 436 437 cal.set(Calendar.YEAR, 2016); 438 cal.set(Calendar.MONTH, Calendar.DECEMBER); 439 cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH)); 440 Date initialDate = cal.getTime(); 441 442 GuidedDatePickerAction action = new GuidedDatePickerAction.Builder( 443 mContext) 444 .id(0) 445 .title("Date") 446 .date(initialDate.getTime()) 447 .datePickerFormat("DMY") 448 .build(); 449 450 actionList.add(action); 451 452 GuidedStepAttributesTestFragment.clear(); 453 GuidedStepAttributesTestFragment.GUIDANCE = guidance; 454 GuidedStepAttributesTestFragment.ACTION_LIST = actionList; 455 456 initActivity(intent); 457 458 DatePicker mPickerView = (DatePicker) mActivity.findViewById( 459 R.id.guidedactions_activator_item); 460 461 verticalScrollToFieldValue(Calendar.MONTH, Calendar.NOVEMBER, new int[] {0, 1, 2}, 462 mPickerView, KeyEvent.KEYCODE_DPAD_UP); 463 long executionTime = System.currentTimeMillis() - startTime; 464 Log.d(TAG, "testDecemberToNovember() Execution time: " + executionTime); 465 Thread.sleep(FINAL_WAIT); 466 } 467 468 @Test 469 public void testNovemberToOctoberTransition() throws Throwable { 470 long startTime = System.currentTimeMillis(); 471 Intent intent = new Intent(); 472 473 String title = "Date Picker Transition Test"; 474 String breadcrumb = "Month Transition Test Demo"; 475 String description = "Testing the transition from Nov to Oct"; 476 GuidanceStylist.Guidance guidance = new GuidanceStylist.Guidance(title, description, 477 breadcrumb, null); 478 479 List<GuidedAction> actionList = new ArrayList<>(); 480 481 Calendar cal = Calendar.getInstance(); 482 483 cal.set(Calendar.YEAR, 2016); 484 cal.set(Calendar.MONTH, Calendar.NOVEMBER); 485 cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH)); 486 Date initialDate = cal.getTime(); 487 488 GuidedDatePickerAction action = new GuidedDatePickerAction.Builder( 489 mContext) 490 .id(0) 491 .title("Date") 492 .date(initialDate.getTime()) 493 .datePickerFormat("DMY") 494 .build(); 495 496 actionList.add(action); 497 498 GuidedStepAttributesTestFragment.clear(); 499 GuidedStepAttributesTestFragment.GUIDANCE = guidance; 500 GuidedStepAttributesTestFragment.ACTION_LIST = actionList; 501 502 initActivity(intent); 503 504 DatePicker mPickerView = (DatePicker) mActivity.findViewById( 505 R.id.guidedactions_activator_item); 506 507 verticalScrollToFieldValue(Calendar.MONTH, Calendar.OCTOBER, new int[] {0, 1, 2}, 508 mPickerView, KeyEvent.KEYCODE_DPAD_UP); 509 long executionTime = System.currentTimeMillis() - startTime; 510 Log.d(TAG, "testNovemberToOctober() Execution time: " + executionTime); 511 Thread.sleep(FINAL_WAIT); 512 } 513 514 @Test 515 public void testLeapToNonLeapYearTransition() throws Throwable { 516 long startTime = System.currentTimeMillis(); 517 Intent intent = new Intent(); 518 519 String title = "Date Picker Transition Test"; 520 String breadcrumb = "Leap Year Transition Test Demo"; 521 String description = "Testing Feb transition from leap to nonlneap year"; 522 GuidanceStylist.Guidance guidance = new GuidanceStylist.Guidance(title, description, 523 breadcrumb, null); 524 525 List<GuidedAction> actionList = new ArrayList<>(); 526 527 Calendar cal = Calendar.getInstance(); 528 529 cal.set(Calendar.YEAR, 2016); // 2016 is a leap year 530 cal.set(Calendar.MONTH, Calendar.FEBRUARY); 531 cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH)); 532 Date initialDate = cal.getTime(); 533 534 GuidedDatePickerAction action = new GuidedDatePickerAction.Builder( 535 mContext) 536 .id(0) 537 .title("Date") 538 .date(initialDate.getTime()) 539 .datePickerFormat("DMY") 540 .build(); 541 542 actionList.add(action); 543 544 GuidedStepAttributesTestFragment.clear(); 545 GuidedStepAttributesTestFragment.GUIDANCE = guidance; 546 GuidedStepAttributesTestFragment.ACTION_LIST = actionList; 547 548 initActivity(intent); 549 550 DatePicker mPickerView = (DatePicker) mActivity.findViewById( 551 R.id.guidedactions_activator_item); 552 553 verticalScrollToFieldValue(Calendar.YEAR, 2017, new int[] {0, 1, 2}, 554 mPickerView, KeyEvent.KEYCODE_DPAD_DOWN); 555 long executionTime = System.currentTimeMillis() - startTime; 556 Log.d(TAG, "testLeapToNonLeapYearTransition() Execution time: " + executionTime); 557 Thread.sleep(FINAL_WAIT); 558 } 559 560 @Test 561 public void testNonLeapToLeapYearTransition() throws Throwable { 562 long startTime = System.currentTimeMillis(); 563 Intent intent = new Intent(); 564 565 String title = "Date Picker Transition Test"; 566 String breadcrumb = "Leap Year Transition Test Demo"; 567 String description = "Testing Feb transition from nonleap to leap year"; 568 GuidanceStylist.Guidance guidance = new GuidanceStylist.Guidance(title, description, 569 breadcrumb, null); 570 571 List<GuidedAction> actionList = new ArrayList<>(); 572 573 Calendar cal = Calendar.getInstance(); 574 575 cal.set(Calendar.YEAR, 2017); // 2017 is a non-leap year 576 cal.set(Calendar.MONTH, Calendar.FEBRUARY); 577 cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH)); 578 Date initialDate = cal.getTime(); 579 580 GuidedDatePickerAction action = new GuidedDatePickerAction.Builder( 581 mContext) 582 .id(0) 583 .title("Date") 584 .date(initialDate.getTime()) 585 .datePickerFormat("DMY") 586 .build(); 587 588 actionList.add(action); 589 590 GuidedStepAttributesTestFragment.clear(); 591 GuidedStepAttributesTestFragment.GUIDANCE = guidance; 592 GuidedStepAttributesTestFragment.ACTION_LIST = actionList; 593 594 initActivity(intent); 595 596 DatePicker mPickerView = (DatePicker) mActivity.findViewById( 597 R.id.guidedactions_activator_item); 598 599 verticalScrollToFieldValue(Calendar.YEAR, 2016, new int[] {0, 1, 2}, 600 mPickerView, KeyEvent.KEYCODE_DPAD_UP); 601 long executionTime = System.currentTimeMillis() - startTime; 602 Log.d(TAG, "testNonLeapToLeapYearTransition() Execution time: " + executionTime); 603 Thread.sleep(FINAL_WAIT); 604 } 605 606 private void traverseMonths(DatePicker mPickerView, GuidedDatePickerAction dateAction) 607 throws Throwable { 608 609 final GuidedStepFragment mFragment = (GuidedStepFragment) 610 mActivity.getGuidedStepTestFragment(); 611 612 Calendar currentActionCal = Calendar.getInstance(); 613 currentActionCal.setTimeInMillis(dateAction.getDate()); 614 615 sendKey(KeyEvent.KEYCODE_DPAD_CENTER); 616 Thread.sleep(TRANSITION_LENGTH); 617 618 int prevMonth = -1; 619 int currentMonth = mPickerView.getColumnAt(MONTH_INDEX).getCurrentValue(); 620 while (currentMonth != prevMonth) { 621 int prevDayOfMonth = -1; 622 int currentDayOfMonth = mPickerView.getColumnAt(DAY_INDEX).getCurrentValue(); 623 // scroll down the days till reaching the last day of month 624 while (currentDayOfMonth != prevDayOfMonth) { 625 sendKey(KeyEvent.KEYCODE_DPAD_DOWN); 626 Thread.sleep(VERTICAL_SCROLL_WAIT); 627 prevDayOfMonth = currentDayOfMonth; 628 currentDayOfMonth = mPickerView.getColumnAt(DAY_INDEX).getCurrentValue(); 629 } 630 int oldDayValue = mPickerView.getColumnAt(DAY_INDEX).getCurrentValue(); 631 int oldMonthValue = mPickerView.getColumnAt(MONTH_INDEX).getCurrentValue(); 632 // increment the month 633 sendKey(KeyEvent.KEYCODE_DPAD_RIGHT); 634 Thread.sleep(VERTICAL_SCROLL_WAIT); 635 636 sendKey(KeyEvent.KEYCODE_DPAD_DOWN); 637 Thread.sleep(TRANSITION_LENGTH); 638 639 int newDayValue = mPickerView.getColumnAt(DAY_INDEX).getCurrentValue(); 640 int newMonthValue = mPickerView.getColumnAt(MONTH_INDEX).getCurrentValue(); 641 verifyMonthTransition(currentActionCal, 642 oldDayValue, oldMonthValue, newDayValue, newMonthValue); 643 644 sendKey(KeyEvent.KEYCODE_DPAD_LEFT); 645 Thread.sleep(TRANSITION_LENGTH); 646 prevMonth = currentMonth; 647 currentMonth = newMonthValue; 648 } 649 650 } 651 652 653 private void verifyMonthTransition(Calendar currentCal, int oldDayValue, int oldMonthValue, 654 int newDayValue, int newMonthValue) { 655 656 if (oldMonthValue == newMonthValue) 657 return; 658 659 currentCal.set(Calendar.DAY_OF_MONTH, 1); 660 currentCal.set(Calendar.MONTH, oldMonthValue); 661 int expectedOldDayValue = currentCal.getActualMaximum(Calendar.DAY_OF_MONTH); 662 currentCal.set(Calendar.MONTH, newMonthValue); 663 int numDaysInNewMonth = currentCal.getActualMaximum(Calendar.DAY_OF_MONTH); 664 int expectedNewDayValue = (expectedOldDayValue <= numDaysInNewMonth) 665 ? expectedOldDayValue : numDaysInNewMonth; 666 667 assertTrue(mContext.getString( 668 R.string.datepicker_test_transition_error1, oldMonthValue), 669 oldDayValue == expectedOldDayValue 670 ); 671 assertTrue(mContext.getString( 672 R.string.datepicker_test_transition_error2, newDayValue, newMonthValue), 673 newDayValue == expectedNewDayValue 674 ); 675 } 676 677 @Test 678 public void testDateRangesMDYFormat() throws Throwable { 679 680 long startTime = System.currentTimeMillis(); 681 682 GuidedDatePickerAction[] datePickerActions = setupDateActionsForMinAndMaxRangeTests(); 683 684 scrollToMinAndMaxDates(new int[] {1, 0, 2}, datePickerActions[0]); 685 long executionTime = System.currentTimeMillis() - startTime; 686 Log.d(TAG, "testDateRangesMDYFormat() Execution time: " + executionTime); 687 Thread.sleep(FINAL_WAIT); 688 } 689 690 public void testDateRangesDMYFormat() throws Throwable { 691 692 long startTime = System.currentTimeMillis(); 693 694 GuidedDatePickerAction[] datePickerActions = setupDateActionsForMinAndMaxRangeTests(); 695 Log.d(TAG, "setup dateactions complete!"); 696 scrollToMinAndMaxDates(new int[] {0, 1, 2}, datePickerActions[1]); 697 long executionTime = System.currentTimeMillis() - startTime; 698 Log.d(TAG, "testDateRangesDMYFormat() Execution time: " + executionTime); 699 Thread.sleep(FINAL_WAIT); 700 } 701 702 @Test 703 public void testDateRangesWithYearEqual() throws Throwable { 704 705 long startTime = System.currentTimeMillis(); 706 707 GuidedDatePickerAction[] datePickerActions = setupDateActionsForMinAndMaxRangeTests(); 708 709 scrollToMinAndMaxDates(new int[] {0, 1, 2}, datePickerActions[2]); 710 long executionTime = System.currentTimeMillis() - startTime; 711 Log.d(TAG, "testDateRangesWithYearEqual() Execution time: " + executionTime); 712 Thread.sleep(FINAL_WAIT); 713 } 714 715 @Test 716 public void testDateRangesWithMonthAndYearEqual() throws Throwable { 717 718 long startTime = System.currentTimeMillis(); 719 720 GuidedDatePickerAction[] datePickerActions = setupDateActionsForMinAndMaxRangeTests(); 721 722 scrollToMinAndMaxDates(new int[] {0, 1, 2}, datePickerActions[3]); 723 long executionTime = System.currentTimeMillis() - startTime; 724 Log.d(TAG, "testDateRangesWithMonthAndYearEqual() Execution time: " + executionTime); 725 Thread.sleep(FINAL_WAIT); 726 } 727 728 @Test 729 public void testDateRangesWithAllFieldsEqual() throws Throwable { 730 731 long startTime = System.currentTimeMillis(); 732 733 GuidedDatePickerAction[] datePickerActions = setupDateActionsForMinAndMaxRangeTests(); 734 735 scrollToMinAndMaxDates(new int[] {0, 1, 2}, datePickerActions[4]); 736 long executionTime = System.currentTimeMillis() - startTime; 737 Log.d(TAG, "testDateRangesWithAllFieldsEqual() Execution time: " + executionTime); 738 Thread.sleep(FINAL_WAIT); 739 } 740 741 private GuidedDatePickerAction[] setupDateActionsForMinAndMaxRangeTests() { 742 Intent intent = new Intent(); 743 Resources res = mContext.getResources(); 744 745 SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy"); 746 747 Calendar currCal = Calendar.getInstance(); 748 currCal.set(Calendar.YEAR, 2016); 749 currCal.set(Calendar.MONTH, Calendar.JULY); 750 currCal.set(Calendar.DAY_OF_MONTH, 15); 751 752 Calendar minCal = Calendar.getInstance(); 753 minCal.set(Calendar.YEAR, 2014); 754 minCal.set(Calendar.MONTH, Calendar.OCTOBER); 755 minCal.set(Calendar.DAY_OF_MONTH, 20); 756 757 Calendar maxCal = Calendar.getInstance(); 758 maxCal.set(Calendar.YEAR, 2018); 759 maxCal.set(Calendar.MONTH, Calendar.FEBRUARY); 760 maxCal.set(Calendar.DAY_OF_MONTH, 10); 761 762 String title = "Date Picker Range Test"; 763 String breadcrumb = "Date Picker Range Test Demo"; 764 String description = ""; 765 GuidanceStylist.Guidance guidance = new GuidanceStylist.Guidance(title, description, 766 breadcrumb, null); 767 768 List<GuidedAction> actionList = new ArrayList<>(); 769 770 // testing different date formats and the correctness of range changes as we scroll 771 GuidedDatePickerAction dateAction1 = new GuidedDatePickerAction.Builder( 772 mContext) 773 .id(0) 774 .title(res.getString(R.string.datepicker_with_range_title, 775 dateFormat.format(minCal.getTime()), 776 dateFormat.format(maxCal.getTime()))) 777 .multilineDescription(true) 778 .date(currCal.getTimeInMillis()) 779 .datePickerFormat("MDY") 780 .minDate(minCal.getTimeInMillis()) 781 .maxDate(maxCal.getTimeInMillis()) 782 .build(); 783 784 GuidedDatePickerAction dateAction2 = new GuidedDatePickerAction.Builder( 785 mContext) 786 .id(1) 787 .title(res.getString(R.string.datepicker_with_range_title, 788 dateFormat.format(minCal.getTimeInMillis()), 789 dateFormat.format(maxCal.getTimeInMillis()))) 790 .multilineDescription(true) 791 .date(currCal.getTimeInMillis()) 792 .datePickerFormat("DMY") 793 .minDate(minCal.getTimeInMillis()) 794 .maxDate(maxCal.getTimeInMillis()) 795 .build(); 796 797 // testing date ranges when Year is equal 798 minCal.set(Calendar.YEAR, maxCal.get(Calendar.YEAR)); 799 int minMonth = Math.min(minCal.get(Calendar.MONTH), maxCal.get(Calendar.MONTH)); 800 int maxMonth = Math.max(minCal.get(Calendar.MONTH), maxCal.get(Calendar.MONTH)); 801 minCal.set(Calendar.MONTH, minMonth); 802 maxCal.set(Calendar.MONTH, maxMonth); 803 804 GuidedDatePickerAction dateAction3 = new GuidedDatePickerAction.Builder( 805 mContext) 806 .id(2) 807 .title(res.getString(R.string.datepicker_with_range_title, 808 dateFormat.format(minCal.getTimeInMillis()), 809 dateFormat.format(maxCal.getTimeInMillis()))) 810 .multilineDescription(true) 811 .date(currCal.getTimeInMillis()) 812 .datePickerFormat("DMY") 813 .minDate(minCal.getTimeInMillis()) 814 .maxDate(maxCal.getTimeInMillis()) 815 .build(); 816 817 818 // testing date ranges when both Month and Year are equal 819 minCal.set(Calendar.MONTH, maxCal.get(Calendar.MONTH)); 820 int minDay = Math.min(minCal.get(Calendar.DAY_OF_MONTH), maxCal.get(Calendar.DAY_OF_MONTH)); 821 int maxDay = Math.max(minCal.get(Calendar.DAY_OF_MONTH), maxCal.get(Calendar.DAY_OF_MONTH)); 822 minCal.set(Calendar.DAY_OF_MONTH, minDay); 823 maxCal.set(Calendar.DAY_OF_MONTH, maxDay); 824 825 GuidedDatePickerAction dateAction4 = new GuidedDatePickerAction.Builder( 826 mContext) 827 .id(3) 828 .title(res.getString(R.string.datepicker_with_range_title, 829 dateFormat.format(minCal.getTimeInMillis()), 830 dateFormat.format(maxCal.getTimeInMillis()))) 831 .multilineDescription(true) 832 .date(currCal.getTimeInMillis()) 833 .datePickerFormat("DMY") 834 .minDate(minCal.getTimeInMillis()) 835 .maxDate(maxCal.getTimeInMillis()) 836 .build(); 837 838 839 // testing date ranges when all fields are equal 840 minCal.set(Calendar.DAY_OF_MONTH, maxCal.get(Calendar.DAY_OF_MONTH)); 841 842 GuidedDatePickerAction dateAction5 = new GuidedDatePickerAction.Builder( 843 mContext) 844 .id(4) 845 .title(res.getString(R.string.datepicker_with_range_title, 846 dateFormat.format(minCal.getTimeInMillis()), 847 dateFormat.format(maxCal.getTimeInMillis()))) 848 .multilineDescription(true) 849 .date(currCal.getTimeInMillis()) 850 .datePickerFormat("DMY") 851 .minDate(minCal.getTimeInMillis()) 852 .maxDate(maxCal.getTimeInMillis()) 853 .build(); 854 855 actionList.add(dateAction1); 856 actionList.add(dateAction2); 857 actionList.add(dateAction3); 858 actionList.add(dateAction4); 859 actionList.add(dateAction5); 860 861 GuidedStepAttributesTestFragment.clear(); 862 GuidedStepAttributesTestFragment.GUIDANCE = guidance; 863 GuidedStepAttributesTestFragment.ACTION_LIST = actionList; 864 865 initActivity(intent); 866 return new GuidedDatePickerAction[] {dateAction1, dateAction2, dateAction3, dateAction4, 867 dateAction5}; 868 } 869 870 private void scrollToMinAndMaxDates(int[] columnIndices, GuidedDatePickerAction dateAction) 871 throws Throwable{ 872 873 final GuidedStepFragment mFragment = (GuidedStepFragment) 874 mActivity.getGuidedStepTestFragment(); 875 876 VerticalGridView guidedActionsList = (VerticalGridView) 877 mActivity.findViewById(R.id.guidedactions_list); 878 879 int currSelectedAction = mFragment.getSelectedActionPosition(); 880 // scroll up/down to the requested action 881 long verticalScrollOffset = dateAction.getId() - currSelectedAction; 882 883 int verticalScrollDir = KeyEvent.KEYCODE_DPAD_DOWN; 884 if (verticalScrollOffset < 0) { 885 verticalScrollOffset= -verticalScrollOffset; 886 verticalScrollDir = KeyEvent.KEYCODE_DPAD_UP; 887 } 888 for(int i = 0; i < verticalScrollOffset; i++) { 889 sendKey(verticalScrollDir); 890 Thread.sleep(TRANSITION_LENGTH); 891 } 892 893 assertTrue("The wrong action was selected!", mFragment.getSelectedActionPosition() 894 == dateAction.getId()); 895 DatePicker mPickerView = (DatePicker) mFragment.getActionItemView((int) dateAction.getId()) 896 .findViewById(R.id.guidedactions_activator_item); 897 898 Calendar currentActionCal = Calendar.getInstance(); 899 currentActionCal.setTimeInMillis(dateAction.getDate()); 900 901 902 // scrolling to the minimum date 903 904 verticalScrollToFieldValue(Calendar.YEAR, -1, columnIndices, mPickerView, 905 KeyEvent.KEYCODE_DPAD_UP); 906 dateAction.setDate(mPickerView.getDate()); 907 908 verticalScrollToFieldValue(Calendar.MONTH, -1, columnIndices, mPickerView, 909 KeyEvent.KEYCODE_DPAD_UP); 910 dateAction.setDate(mPickerView.getDate()); 911 912 verticalScrollToFieldValue(Calendar.DAY_OF_MONTH, -1, columnIndices, mPickerView, 913 KeyEvent.KEYCODE_DPAD_UP); 914 dateAction.setDate(mPickerView.getDate()); 915 916 Thread.sleep(VERTICAL_SCROLL_WAIT); 917 918 // now scrolling to the maximum date 919 920 verticalScrollToFieldValue(Calendar.YEAR, -1, columnIndices, mPickerView, 921 KeyEvent.KEYCODE_DPAD_DOWN); 922 dateAction.setDate(mPickerView.getDate()); 923 924 verticalScrollToFieldValue(Calendar.MONTH, -1, columnIndices, mPickerView, 925 KeyEvent.KEYCODE_DPAD_DOWN); 926 dateAction.setDate(mPickerView.getDate()); 927 928 verticalScrollToFieldValue(Calendar.DAY_OF_MONTH, -1, columnIndices, mPickerView, 929 KeyEvent.KEYCODE_DPAD_DOWN); 930 dateAction.setDate(mPickerView.getDate()); 931 932 sendKey(KeyEvent.KEYCODE_DPAD_CENTER); 933 Thread.sleep(TRANSITION_LENGTH); 934 } 935 936} 937