blob: 28ea163e7f8bdd5690d97a14551372d2875430cb [file] [log] [blame]
/*
* 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<Boolean> 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<Boolean> 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<Boolean> searchCondition) {
return waitForCondition(uiDevice, searchCondition, Constants.MAX_SHOW_DELAY_MILLIS);
}
private static boolean waitForCondition(
UiDevice uiDevice, SearchCondition<Boolean> 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}.
*
* <p>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}.
*
* <p>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<Boolean> 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() {}
}