package com.lukekorth.deviceautomator; import android.graphics.Rect; import androidx.test.uiautomator.By; import androidx.test.uiautomator.UiDevice; import androidx.test.uiautomator.UiObject; import androidx.test.uiautomator.UiObjectNotFoundException; import org.hamcrest.Matcher; import org.hamcrest.StringDescription; import static androidx.test.InstrumentationRegistry.getInstrumentation; import static junit.framework.Assert.assertTrue; import static junit.framework.Assert.fail; /** * A collection of assertions for use with {@link DeviceAutomator}. */ public abstract class AutomatorAssertion { /** * Asserts that the ui element specified in {@link DeviceAutomator#onDevice(UiObjectMatcher)} * is visible. * * @return */ public static AutomatorAssertion visible(final boolean visible) { return new AutomatorAssertion() { @Override public void wrappedCheck(UiObject object) throws UiObjectNotFoundException { try { Rect bounds = object.getVisibleBounds(); if (bounds == null) { fail("Matched view did not have any visible bounds"); } if (visible) { assertTrue("Matched view was not visible", bounds.width() > 0); assertTrue("Matched view was not visible", bounds.height() > 0); } else { assertTrue("Matched view was visible", bounds.width() == 0); assertTrue("Matched view was visible", bounds.height() == 0); } } catch (UiObjectNotFoundException e) { if (visible) { fail(e.getMessage()); } } } }; } /** * Asserts that the ui element specified in {@link DeviceAutomator#onDevice(UiObjectMatcher)} * has text that matches the given matcher. * * @param matcher The <a href="http://hamcrest.org/JavaHamcrest/">Hamcrest</a> to match against. * @return */ public static AutomatorAssertion text(final Matcher matcher) { return new AutomatorAssertion() { @Override public void wrappedCheck(UiObject object) throws UiObjectNotFoundException { visible(true).check(object); if (!matcher.matches(object.getText())) { StringDescription description = new StringDescription(); description.appendText("Expected "); matcher.describeTo(description); description.appendText(" "); matcher.describeMismatch(object.getText(), description); assertTrue(description.toString(), false); } } }; } /** * Asserts that the ui element specified in {@link DeviceAutomator#onDevice(UiObjectMatcher)} * has a content description that matches the given matcher. * * @param matcher The <a href="http://hamcrest.org/JavaHamcrest/">Hamcrest</a> to match against. * @return */ public static AutomatorAssertion contentDescription(final Matcher matcher) { return new AutomatorAssertion() { @Override public void wrappedCheck(UiObject object) throws UiObjectNotFoundException { visible(true).check(object); if (!matcher.matches(object.getContentDescription())) { StringDescription description = new StringDescription(); description.appendText("Expected "); matcher.describeTo(description); description.appendText(" "); matcher.describeMismatch(object.getText(), description); assertTrue(description.toString(), false); } } }; } /** * Asserts that the foreground app is the package specified. * * @param packageName The package to check for. * @return */ public static AutomatorAssertion foregroundAppIs(final String packageName) { return new AutomatorAssertion() { @Override public void wrappedCheck(UiObject object) throws UiObjectNotFoundException { assertTrue(UiDevice.getInstance(getInstrumentation()).hasObject(By.pkg(packageName))); } }; } void check(UiObject object) { try { wrappedCheck(object); } catch (UiObjectNotFoundException e) { throw new RuntimeException(e); } } public abstract void wrappedCheck(UiObject object) throws UiObjectNotFoundException; }