/* * Copyright (C) 2015 The Android Open Source Project * * 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.android.tv.testing.uihelper; import static com.android.tv.testing.uihelper.Constants.FOCUSED_VIEW; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertNotNull; import static junit.framework.Assert.assertTrue; import android.support.test.uiautomator.By; import android.support.test.uiautomator.BySelector; import android.support.test.uiautomator.Direction; import android.support.test.uiautomator.SearchCondition; import android.support.test.uiautomator.UiDevice; import android.support.test.uiautomator.UiObject2; import android.support.test.uiautomator.Until; import junit.framework.Assert; /** * Asserts for {@link UiDevice}s. */ public final class UiDeviceAsserts { public static void assertHas(UiDevice uiDevice, BySelector bySelector, boolean expected) { assertEquals("Has " + bySelector, expected, uiDevice.hasObject(bySelector)); } public static void assertWaitUntilFocused(UiDevice uiDevice, BySelector bySelector) { UiObject2 uiObject = uiDevice.findObject(bySelector); assertNotNull(uiObject); assertTrue(uiObject.wait(Until.focused(true), Constants.MAX_FOCUSED_DELAY_MILLIS)); } /** * Assert that {@code searchCondition} becomes true within * {@value Constants#MAX_SHOW_DELAY_MILLIS} milliseconds. * * @param uiDevice the device under test. * @param searchCondition the condition to wait for. */ public static void assertWaitForCondition(UiDevice uiDevice, SearchCondition searchCondition) { assertWaitForCondition(uiDevice, searchCondition, Constants.MAX_SHOW_DELAY_MILLIS); } /** * Assert that {@code searchCondition} becomes true within {@code timeout} milliseconds. * * @param uiDevice the device under test. * @param searchCondition the condition to wait for. */ public static void assertWaitForCondition(UiDevice uiDevice, SearchCondition searchCondition, long timeout) { boolean result = waitForCondition(uiDevice, searchCondition, timeout); assertTrue(searchCondition + " not true after " + timeout / 1000.0 + " seconds.", result); } /** * Wait until {@code searchCondition} becomes true. * * @param uiDevice The device under test. * @param searchCondition The condition to wait for. * @return {@code true} if the condition is met, otherwise {@code false}. */ public static boolean waitForCondition(UiDevice uiDevice, SearchCondition searchCondition) { return waitForCondition(uiDevice, searchCondition, Constants.MAX_SHOW_DELAY_MILLIS); } private static boolean waitForCondition(UiDevice uiDevice, SearchCondition searchCondition, long timeout) { long adjustedTimeout = timeout + Math.max(Constants.MIN_EXTRA_TIMEOUT, (long) (timeout * Constants.EXTRA_TIMEOUT_PERCENT)); return uiDevice.wait(searchCondition, adjustedTimeout); } /** * Navigates through the focus items in a container returning the container child that has a * descendant matching the {@code selector}. *

* The navigation starts in the {@code direction} specified and * {@link Direction#reverse(Direction) reverses} once if needed. Fails if there is not a * focused * descendant, or if after completing both directions no focused child has a descendant * matching * {@code selector}. *

* Fails if the menu item can not be navigated to. * * @param uiDevice the device under test. * @param container contains children to navigate over. * @param selector the selector for the object to navigate to. * @param direction the direction to start navigating. * @return the object navigated to. */ public static UiObject2 assertNavigateTo(UiDevice uiDevice, UiObject2 container, BySelector selector, Direction direction) { int count = 0; while (count < 2) { BySelector hasFocusedDescendant = By.hasDescendant(FOCUSED_VIEW); UiObject2 focusedChild = null; SearchCondition untilHasFocusedDescendant = Until .hasObject(hasFocusedDescendant); boolean result = container.wait(untilHasFocusedDescendant, UiObject2Asserts.getAdjustedTimeout(Constants.MAX_SHOW_DELAY_MILLIS)); if (!result) { // HACK: Try direction anyways because play control does not always have a // focused item. UiDeviceUtils.pressDpad(uiDevice, direction); UiObject2Asserts.assertWaitForCondition(container, untilHasFocusedDescendant); } for (UiObject2 c : container.getChildren()) { if (c.isFocused() || c.hasObject(hasFocusedDescendant)) { focusedChild = c; break; } } if (focusedChild == null) { Assert.fail("No focused item found in container " + container); } if (focusedChild.hasObject(selector)) { return focusedChild; } if (!UiObject2Utils.hasSiblingInDirection(focusedChild, direction)) { direction = Direction.reverse(direction); count++; } UiDeviceUtils.pressDpad(uiDevice, direction); } Assert.fail("Could not find item with " + selector); return null; } private UiDeviceAsserts() { } }