1 /* 2 * Copyright (C) 2015 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 package com.android.tv.testing.uihelper; 17 18 import static com.android.tv.testing.uihelper.Constants.FOCUSED_VIEW; 19 import static junit.framework.Assert.assertEquals; 20 import static junit.framework.Assert.assertNotNull; 21 import static junit.framework.Assert.assertTrue; 22 23 import android.support.test.uiautomator.By; 24 import android.support.test.uiautomator.BySelector; 25 import android.support.test.uiautomator.Direction; 26 import android.support.test.uiautomator.SearchCondition; 27 import android.support.test.uiautomator.UiDevice; 28 import android.support.test.uiautomator.UiObject2; 29 import android.support.test.uiautomator.Until; 30 import junit.framework.Assert; 31 32 /** Asserts for {@link UiDevice}s. */ 33 public final class UiDeviceAsserts { 34 assertHas(UiDevice uiDevice, BySelector bySelector, boolean expected)35 public static void assertHas(UiDevice uiDevice, BySelector bySelector, boolean expected) { 36 assertEquals("Has " + bySelector, expected, uiDevice.hasObject(bySelector)); 37 } 38 assertWaitUntilFocused(UiDevice uiDevice, BySelector bySelector)39 public static void assertWaitUntilFocused(UiDevice uiDevice, BySelector bySelector) { 40 UiObject2 uiObject = uiDevice.findObject(bySelector); 41 assertNotNull(uiObject); 42 assertTrue(uiObject.wait(Until.focused(true), Constants.MAX_FOCUSED_DELAY_MILLIS)); 43 } 44 45 /** 46 * Assert that {@code searchCondition} becomes true within {@value 47 * Constants#MAX_SHOW_DELAY_MILLIS} milliseconds. 48 * 49 * @param uiDevice the device under test. 50 * @param searchCondition the condition to wait for. 51 */ assertWaitForCondition( UiDevice uiDevice, SearchCondition<Boolean> searchCondition)52 public static void assertWaitForCondition( 53 UiDevice uiDevice, SearchCondition<Boolean> searchCondition) { 54 assertWaitForCondition(uiDevice, searchCondition, Constants.MAX_SHOW_DELAY_MILLIS); 55 } 56 57 /** 58 * Assert that {@code searchCondition} becomes true within {@code timeout} milliseconds. 59 * 60 * @param uiDevice the device under test. 61 * @param searchCondition the condition to wait for. 62 */ assertWaitForCondition( UiDevice uiDevice, SearchCondition<Boolean> searchCondition, long timeout)63 public static void assertWaitForCondition( 64 UiDevice uiDevice, SearchCondition<Boolean> searchCondition, long timeout) { 65 boolean result = waitForCondition(uiDevice, searchCondition, timeout); 66 assertTrue(searchCondition + " not true after " + timeout / 1000.0 + " seconds.", result); 67 } 68 69 /** 70 * Wait until {@code searchCondition} becomes true. 71 * 72 * @param uiDevice The device under test. 73 * @param searchCondition The condition to wait for. 74 * @return {@code true} if the condition is met, otherwise {@code false}. 75 */ waitForCondition( UiDevice uiDevice, SearchCondition<Boolean> searchCondition)76 public static boolean waitForCondition( 77 UiDevice uiDevice, SearchCondition<Boolean> searchCondition) { 78 return waitForCondition(uiDevice, searchCondition, Constants.MAX_SHOW_DELAY_MILLIS); 79 } 80 waitForCondition( UiDevice uiDevice, SearchCondition<Boolean> searchCondition, long timeout)81 private static boolean waitForCondition( 82 UiDevice uiDevice, SearchCondition<Boolean> searchCondition, long timeout) { 83 long adjustedTimeout = 84 timeout 85 + Math.max( 86 Constants.MIN_EXTRA_TIMEOUT, 87 (long) (timeout * Constants.EXTRA_TIMEOUT_PERCENT)); 88 return uiDevice.wait(searchCondition, adjustedTimeout); 89 } 90 91 /** 92 * Navigates through the focus items in a container returning the container child that has a 93 * descendant matching the {@code selector}. 94 * 95 * <p>The navigation starts in the {@code direction} specified and {@link 96 * Direction#reverse(Direction) reverses} once if needed. Fails if there is not a focused 97 * descendant, or if after completing both directions no focused child has a descendant matching 98 * {@code selector}. 99 * 100 * <p>Fails if the menu item can not be navigated to. 101 * 102 * @param uiDevice the device under test. 103 * @param container contains children to navigate over. 104 * @param selector the selector for the object to navigate to. 105 * @param direction the direction to start navigating. 106 * @return the object navigated to. 107 */ assertNavigateTo( UiDevice uiDevice, UiObject2 container, BySelector selector, Direction direction)108 public static UiObject2 assertNavigateTo( 109 UiDevice uiDevice, UiObject2 container, BySelector selector, Direction direction) { 110 int count = 0; 111 while (count < 2) { 112 BySelector hasFocusedDescendant = By.hasDescendant(FOCUSED_VIEW); 113 UiObject2 focusedChild = null; 114 SearchCondition<Boolean> untilHasFocusedDescendant = 115 Until.hasObject(hasFocusedDescendant); 116 117 boolean result = 118 container.wait( 119 untilHasFocusedDescendant, 120 UiObject2Asserts.getAdjustedTimeout(Constants.MAX_SHOW_DELAY_MILLIS)); 121 if (!result) { 122 // HACK: Try direction anyways because play control does not always have a 123 // focused item. 124 UiDeviceUtils.pressDpad(uiDevice, direction); 125 UiObject2Asserts.assertWaitForCondition(container, untilHasFocusedDescendant); 126 } 127 128 for (UiObject2 c : container.getChildren()) { 129 if (c.isFocused() || c.hasObject(hasFocusedDescendant)) { 130 focusedChild = c; 131 break; 132 } 133 } 134 if (focusedChild == null) { 135 Assert.fail("No focused item found in container " + container); 136 } 137 if (focusedChild.hasObject(selector)) { 138 return focusedChild; 139 } 140 if (!UiObject2Utils.hasSiblingInDirection(focusedChild, direction)) { 141 direction = Direction.reverse(direction); 142 count++; 143 } 144 UiDeviceUtils.pressDpad(uiDevice, direction); 145 } 146 Assert.fail("Could not find item with " + selector); 147 return null; 148 } 149 UiDeviceAsserts()150 private UiDeviceAsserts() {} 151 } 152