androidx.test.espresso.util.HumanReadables Java Examples

The following examples show how to use androidx.test.espresso.util.HumanReadables. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: CheckAssertionAction.java    From EspressoDescendantActions with Apache License 2.0 6 votes vote down vote up
@Override
public void perform(UiController uiController, View view) {
    if (viewAssertion == null) {
        throw new NullPointerException("View assertion is null");
    }

    try {
        viewAssertion.check(view, null);
    }
    catch (Throwable e) {
        throw new PerformException.Builder()
                .withActionDescription(getDescription())
                .withViewDescription(HumanReadables.describe(view))
                .withCause(e)
                .build();
    }
}
 
Example #2
Source File: AmbiguousViewMatcherException.java    From android-test with Apache License 2.0 6 votes vote down vote up
private static String getErrorMessage(Builder builder) {
  String errorMessage = "";
  if (builder.includeViewHierarchy) {
    ImmutableSet<View> ambiguousViews =
        ImmutableSet.<View>builder()
            .add(builder.view1, builder.view2)
            .add(builder.others)
            .build();
    errorMessage =
        HumanReadables.getViewHierarchyErrorMessage(
            builder.rootView,
            Lists.newArrayList(ambiguousViews),
            String.format(
                Locale.ROOT,
                "'%s' matches multiple views in the hierarchy.",
                builder.viewMatcher),
            "****MATCHES****");
  } else {
    errorMessage =
        String.format(
            Locale.ROOT, "Multiple Ambiguous Views found for matcher %s", builder.viewMatcher);
  }
  return errorMessage;
}
 
Example #3
Source File: NoMatchingViewException.java    From android-test with Apache License 2.0 6 votes vote down vote up
private static String getErrorMessage(Builder builder) {
  String errorMessage = "";
  if (builder.includeViewHierarchy) {
    String message =
        String.format(
            Locale.ROOT, "No views in hierarchy found matching: %s", builder.viewMatcher);
    if (builder.adapterViewWarning.isPresent()) {
      message = message + builder.adapterViewWarning.get();
    }
    errorMessage =
        HumanReadables.getViewHierarchyErrorMessage(
            builder.rootView, null /* problemViews */, message, null /* problemViewSuffix */);
  } else {
    errorMessage =
        String.format(Locale.ROOT, "Could not find a view that matches %s", builder.viewMatcher);
  }
  return errorMessage;
}
 
Example #4
Source File: ViewMatchers.java    From android-test with Apache License 2.0 6 votes vote down vote up
/**
 * A replacement for MatcherAssert.assertThat that renders View objects nicely.
 *
 * @param message the message to display.
 * @param actual the actual value.
 * @param matcher a matcher that accepts or rejects actual.
 */
public static <T> void assertThat(String message, T actual, Matcher<T> matcher) {
  if (!matcher.matches(actual)) {
    Description description = new StringDescription();
    description
        .appendText(message)
        .appendText("\nExpected: ")
        .appendDescriptionOf(matcher)
        .appendText("\n     Got: ");
    if (actual instanceof View) {
      description.appendValue(HumanReadables.describe((View) actual));
    } else {
      description.appendValue(actual);
    }
    description.appendText("\n");
    throw new AssertionFailedError(description.toString());
  }
}
 
Example #5
Source File: RepeatActionUntilViewState.java    From android-test with Apache License 2.0 6 votes vote down vote up
@Override
public void perform(UiController uiController, View view) {
  int noOfAttempts = 1;
  for (; !mDesiredStateMatcher.matches(view) && noOfAttempts <= mMaxAttempts; noOfAttempts++) {
    mAction.perform(uiController, view);
    uiController.loopMainThreadUntilIdle();
  }
  if (noOfAttempts > mMaxAttempts) {
    throw new PerformException.Builder()
        .withActionDescription(this.getDescription())
        .withViewDescription(HumanReadables.describe(view))
        .withCause(
            new RuntimeException(
                String.format(
                    Locale.ROOT, "Failed to achieve view state after %d attempts", mMaxAttempts)))
        .build();
  }
}
 
Example #6
Source File: ScrollToAction.java    From android-test with Apache License 2.0 6 votes vote down vote up
@Override
public void perform(UiController uiController, View view) {
  if (isDisplayingAtLeast(90).matches(view)) {
    Log.i(TAG, "View is already displayed. Returning.");
    return;
  }
  Rect rect = new Rect();
  view.getDrawingRect(rect);
  if (!view.requestRectangleOnScreen(rect, true /* immediate */)) {
    Log.w(TAG, "Scrolling to view was requested, but none of the parents scrolled.");
  }
  uiController.loopMainThreadUntilIdle();
  if (!isDisplayingAtLeast(90).matches(view)) {
    throw new PerformException.Builder()
        .withActionDescription(this.getDescription())
        .withViewDescription(HumanReadables.describe(view))
        .withCause(
            new RuntimeException(
                "Scrolling to view was attempted, but the view is not displayed"))
        .build();
  }
}
 
Example #7
Source File: CloseKeyboardAction.java    From android-test with Apache License 2.0 6 votes vote down vote up
@Override
public void perform(UiController uiController, View view) {
  // Retry in case of timeout exception to avoid flakiness in IMM.
  for (int i = 0; i < NUM_RETRIES; i++) {
    try {
      tryToCloseKeyboard(view, uiController);
      return;
    } catch (TimeoutException te) {
      Log.w(TAG, "Caught timeout exception. Retrying.");
      if (i == 2) {
        throw new PerformException.Builder()
            .withActionDescription(this.getDescription())
            .withViewDescription(HumanReadables.describe(view))
            .withCause(te)
            .build();
      }
    }
  }
}
 
Example #8
Source File: RecyclerViewActions.java    From android-test with Apache License 2.0 6 votes vote down vote up
@Override
public void perform(UiController uiController, View root) {
  RecyclerView recyclerView = (RecyclerView) root;
  try {
    scroller.perform(uiController, root);
    uiController.loopMainThreadUntilIdle();
    // the above scroller has checked bounds, dupes (maybe) and brought the element into screen.
    int max = atPosition == NO_POSITION ? 2 : atPosition + 1;
    int selectIndex = atPosition == NO_POSITION ? 0 : atPosition;
    List<MatchedItem> matchedItems = itemsMatching(recyclerView, viewHolderMatcher, max);
    actionOnItemAtPosition(matchedItems.get(selectIndex).position, viewAction)
        .perform(uiController, root);
    uiController.loopMainThreadUntilIdle();
  } catch (RuntimeException e) {
    throw new PerformException.Builder()
        .withActionDescription(this.getDescription())
        .withViewDescription(HumanReadables.describe(root))
        .withCause(e)
        .build();
  }
}
 
Example #9
Source File: NestedScrollTo.java    From Kore with Apache License 2.0 6 votes vote down vote up
@Override
public void perform(UiController uiController, View view) {
    if (isDisplayingAtLeast(90).matches(view)) {
        LogUtils.LOGI(TAG, "View is already displayed. Returning.");
        return;
    }
    Rect rect = new Rect();
    view.getDrawingRect(rect);
    if (!view.requestRectangleOnScreen(rect, true /* immediate */)) {
        LogUtils.LOGW(TAG, "Scrolling to view was requested, but none of the parents scrolled.");
    }
    uiController.loopMainThreadUntilIdle();
    if (!isDisplayingAtLeast(90).matches(view)) {
        throw new PerformException.Builder()
                .withActionDescription(this.getDescription())
                .withViewDescription(HumanReadables.describe(view))
                .withCause(new RuntimeException(
                        "Scrolling to view was attempted, but the view is not displayed"))
                .build();
    }
}
 
Example #10
Source File: OpenLinkAction.java    From android-test with Apache License 2.0 5 votes vote down vote up
@Override
public void perform(UiController uiController, View view) {
  TextView textView = (TextView) view;
  String allText = textView.getText().toString();
  URLSpan[] urls = textView.getUrls();
  Spanned spanned = (Spanned) textView.getText();

  // TODO: what if we get more than one hit? For now, take the first one...
  // In the future, we may want to support a way to disambiguate (e.g using text around the link).
  List<String> allLinks = Lists.newArrayList();
  for (URLSpan url : urls) {
    int start = spanned.getSpanStart(url);
    checkState(start != -1, "Unable to get start of text associated with url: " + url);
    int end = spanned.getSpanEnd(url);
    checkState(end != -1, "Unable to get end of text associated with url: " + url);
    String linkText = allText.substring(start, end);
    allLinks.add(linkText);
    if (linkTextMatcher.matches(linkText) && uriMatcher.matches(Uri.parse(url.getURL()))) {
      url.onClick(view);
      return;
    }
  }
  throw new PerformException.Builder()
      .withActionDescription(this.getDescription())
      .withViewDescription(HumanReadables.describe(view))
      .withCause(
          new RuntimeException(
              String.format(
                  Locale.ROOT,
                  "Link with text '%s' and uri '%s' not found. List of links found in this view:"
                      + " %s\n"
                      + "List of uris: %s",
                  linkTextMatcher,
                  uriMatcher,
                  allLinks,
                  Arrays.asList(urls))))
      .build();
}
 
Example #11
Source File: CloseKeyboardAction.java    From android-test with Apache License 2.0 5 votes vote down vote up
private void tryToCloseKeyboard(View view, UiController uiController) throws TimeoutException {
  InputMethodManager imm =
      (InputMethodManager)
          getRootActivity(uiController).getSystemService(Context.INPUT_METHOD_SERVICE);

  CloseKeyboardIdlingResult idlingResult =
      new CloseKeyboardIdlingResult(new Handler(Looper.getMainLooper()));

  IdlingRegistry.getInstance().register(idlingResult);

  try {

    if (!imm.hideSoftInputFromWindow(view.getWindowToken(), 0, idlingResult)) {
      Log.w(TAG, "Attempting to close soft keyboard, while it is not shown.");
      return;
    }
    // set 2 second timeout
    idlingResult.scheduleTimeout(2000);
    uiController.loopMainThreadUntilIdle();
    if (idlingResult.timedOut) {
      throw new TimeoutException("Wait on operation result timed out.");
    }
  } finally {
    IdlingRegistry.getInstance().unregister(idlingResult);
  }

  if (idlingResult.result != InputMethodManager.RESULT_UNCHANGED_HIDDEN
      && idlingResult.result != InputMethodManager.RESULT_HIDDEN) {
    String error =
        "Attempt to close the soft keyboard did not result in soft keyboard to be hidden."
            + " resultCode = "
            + idlingResult.result;
    Log.e(TAG, error);
    throw new PerformException.Builder()
        .withActionDescription(this.getDescription())
        .withViewDescription(HumanReadables.describe(view))
        .withCause(new RuntimeException(error))
        .build();
  }
}
 
Example #12
Source File: AdapterViewProtocol.java    From android-test with Apache License 2.0 5 votes vote down vote up
@Override
public String toString() {
  Object myData = getData();
  String itsClass = null == myData ? "null" : myData.getClass().getName();
  if (myData instanceof Cursor) {
    myData = HumanReadables.describe((Cursor) myData);
  }
  return String.format(
      Locale.ROOT, "Data: %s (class: %s) token: %s", myData, itsClass, opaqueToken);
}
 
Example #13
Source File: UiControllerImplIntegrationTest.java    From android-test with Apache License 2.0 5 votes vote down vote up
@Test
public void testInjectString() throws InterruptedException {
  final AtomicBoolean requestFocusSucceded = new AtomicBoolean(false);

  try (ActivityScenario<SendActivity> activityScenario =
      ActivityScenario.launch(SendActivity.class)) {
    activityScenario.onActivity(
        activity -> {
          final View view = activity.findViewById(R.id.send_data_to_call_edit_text);
          Log.i("TEST", HumanReadables.describe(view));
          requestFocusSucceded.set(view.requestFocus() && view.hasWindowFocus());
          Log.i("TEST-post", HumanReadables.describe(view));
          focusLatch.countDown();
        });

    assertTrue("requestFocus timed out!", focusLatch.await(2, TimeUnit.SECONDS));
    assertTrue("requestFocus failed.", requestFocusSucceded.get());

    getInstrumentation()
        .runOnMainSync(
            new Runnable() {
              @Override
              public void run() {
                try {
                  injectEventWorked.set(uiController.injectString("Hello! \n&*$$$"));
                  latch.countDown();
                } catch (InjectEventSecurityException e) {
                  injectEventThrewSecurityException.set(true);
                }
              }
            });

    assertFalse(
        "SecurityException exception was thrown.", injectEventThrewSecurityException.get());
    assertTrue("Timed out!", latch.await(20, TimeUnit.SECONDS));
    assertTrue(injectEventWorked.get());
  }
}
 
Example #14
Source File: EditorAction.java    From android-test with Apache License 2.0 5 votes vote down vote up
@Override
public void perform(UiController uiController, View view) {
  EditorInfo editorInfo = new EditorInfo();
  InputConnection inputConnection = view.onCreateInputConnection(editorInfo);
  if (inputConnection == null) {
    throw new PerformException.Builder()
        .withActionDescription(this.toString())
        .withViewDescription(HumanReadables.describe(view))
        .withCause(new IllegalStateException("View does not support input methods"))
        .build();
  }

  int actionId =
      editorInfo.actionId != 0
          ? editorInfo.actionId
          : editorInfo.imeOptions & EditorInfo.IME_MASK_ACTION;

  if (actionId == EditorInfo.IME_ACTION_NONE) {
    throw new PerformException.Builder()
        .withActionDescription(this.getDescription())
        .withViewDescription(HumanReadables.describe(view))
        .withCause(new IllegalStateException("No available action on view"))
        .build();
  }

  if (!inputConnection.performEditorAction(actionId)) {
    throw new PerformException.Builder()
        .withActionDescription(this.getDescription())
        .withViewDescription(HumanReadables.describe(view))
        .withCause(
            new RuntimeException(
                String.format(
                    Locale.ROOT,
                    "Failed to perform action %#x. Input connection no longer valid",
                    actionId)))
        .build();
  }
}
 
Example #15
Source File: ViewInteraction.java    From android-test with Apache License 2.0 5 votes vote down vote up
/**
 * Performs the given action on the view selected by the current view matcher. Should be executed
 * on the main thread.
 *
 * @param viewAction the action to execute.
 */
private void doPerform(final SingleExecutionViewAction viewAction) {
  checkNotNull(viewAction);
  final Matcher<? extends View> constraints = checkNotNull(viewAction.getConstraints());
  uiController.loopMainThreadUntilIdle();
  View targetView = viewFinder.getView();
  Log.i(
      TAG,
      String.format(
          Locale.ROOT,
          "Performing '%s' action on view %s",
          viewAction.getDescription(),
          viewMatcher));
  if (!constraints.matches(targetView)) {
    // TODO: update this to describeMismatch once hamcrest 1.4 is available
    StringDescription stringDescription =
        new StringDescription(
            new StringBuilder(
                "Action will not be performed because the target view "
                    + "does not match one or more of the following constraints:\n"));
    constraints.describeTo(stringDescription);
    stringDescription
        .appendText("\nTarget view: ")
        .appendValue(HumanReadables.describe(targetView));

    if (viewAction.getInnerViewAction() instanceof ScrollToAction
        && isDescendantOfA(isAssignableFrom(AdapterView.class)).matches(targetView)) {
      stringDescription.appendText(
          "\nFurther Info: ScrollToAction on a view inside an AdapterView will not work. "
              + "Use Espresso.onData to load the view.");
    }
    throw new PerformException.Builder()
        .withActionDescription(viewAction.getDescription())
        .withViewDescription(viewMatcher.toString())
        .withCause(new RuntimeException(stringDescription.toString()))
        .build();
  } else {
    viewAction.perform(uiController, targetView);
  }
}
 
Example #16
Source File: DescendantViewAction.java    From EspressoDescendantActions with Apache License 2.0 5 votes vote down vote up
@Override
public void perform(UiController uiController, View view) {

    if (viewAction == null) {
        throw new NullPointerException("View action is null");
    }

    ViewFinder viewFinder = ViewFinderHelper.buildViewFinder(viewMatcher, view);

    View descendantView = viewFinder.getView();

    if (descendantView == null) {
        throw new PerformException.Builder()
                .withActionDescription(getDescription())
                .withViewDescription(HumanReadables.describe(view))
                .withCause(new RuntimeException("Descendant view not found"))
                .build();
    }

    try {
        viewAction.perform(uiController, descendantView);
    }
    catch (Throwable t) {
        throw new PerformException.Builder()
                .withActionDescription(getDescription())
                .withViewDescription(HumanReadables.describe(descendantView))
                .withCause(t)
                .build();
    }
}
 
Example #17
Source File: UiControllerImplIntegrationTest.java    From android-test with Apache License 2.0 5 votes vote down vote up
@Test
public void injectLargeString() throws InterruptedException {
  final AtomicBoolean requestFocusSucceded = new AtomicBoolean(false);

  try (ActivityScenario<SendActivity> activityScenario =
      ActivityScenario.launch(SendActivity.class)) {
    activityScenario.onActivity(
        activity -> {
          final View view = activity.findViewById(R.id.send_data_to_call_edit_text);
          Log.i("TEST", HumanReadables.describe(view));
          requestFocusSucceded.set(view.requestFocus());
          Log.i("TEST-post", HumanReadables.describe(view));

          focusLatch.countDown();
        });

    assertTrue("requestFocus timed out!", focusLatch.await(2, TimeUnit.SECONDS));
    assertTrue("requestFocus failed.", requestFocusSucceded.get());

    getInstrumentation()
        .runOnMainSync(
            new Runnable() {
              @Override
              public void run() {
                try {
                  injectEventWorked.set(
                      uiController.injectString("This is a string with 32 chars!!"));
                  latch.countDown();
                } catch (InjectEventSecurityException e) {
                  injectEventThrewSecurityException.set(true);
                }
              }
            });

    assertFalse(
        "SecurityException exception was thrown.", injectEventThrewSecurityException.get());
    assertTrue("Timed out!", latch.await(20, TimeUnit.SECONDS));
    assertTrue(injectEventWorked.get());
  }
}
 
Example #18
Source File: PositionAssertions.java    From android-test with Apache License 2.0 5 votes vote down vote up
static ViewAssertion relativePositionOf(
    final Matcher<View> viewMatcher, final Position position) {
  checkNotNull(viewMatcher);
  return new ViewAssertion() {
    @Override
    public void check(final View foundView, NoMatchingViewException noViewException) {
      StringDescription description = new StringDescription();
      if (noViewException != null) {
        description.appendText(
            String.format(
                Locale.ROOT,
                "' check could not be performed because view '%s' was not found.\n",
                noViewException.getViewMatcherDescription()));
        Log.e(TAG, description.toString());
        throw noViewException;
      } else {
        // TODO: describe the foundView matcher instead of the foundView itself.
        description
            .appendText("View:")
            .appendText(HumanReadables.describe(foundView))
            .appendText(" is not ")
            .appendText(position.toString())
            .appendText(" view ")
            .appendText(viewMatcher.toString());
        assertThat(
            description.toString(),
            isRelativePosition(
                foundView, findView(viewMatcher, getTopViewGroup(foundView)), position),
            is(true));
      }
    }
  };
}
 
Example #19
Source File: ViewAssertions.java    From android-test with Apache License 2.0 5 votes vote down vote up
@SuppressWarnings("unchecked")
@Override
public void check(View view, NoMatchingViewException noViewException) {
  Preconditions.checkNotNull(view);

  final Predicate<View> viewPredicate =
      new Predicate<View>() {
        @Override
        public boolean apply(View input) {
          return selector.matches(input);
        }
      };

  Iterator<View> selectedViewIterator =
      Iterables.filter(breadthFirstViewTraversal(view), viewPredicate).iterator();

  List<View> nonMatchingViews = new ArrayList<>();
  while (selectedViewIterator.hasNext()) {
    View selectedView = selectedViewIterator.next();

    if (!matcher.matches(selectedView)) {
      nonMatchingViews.add(selectedView);
    }
  }

  if (nonMatchingViews.size() > 0) {
    String errorMessage =
        HumanReadables.getViewHierarchyErrorMessage(
            view,
            nonMatchingViews,
            String.format(
                Locale.ROOT,
                "At least one view did not match the required matcher: %s",
                matcher),
            "****DOES NOT MATCH****");
    throw new AssertionFailedError(errorMessage);
  }
}
 
Example #20
Source File: ViewAssertions.java    From android-test with Apache License 2.0 5 votes vote down vote up
@Override
public void check(View view, NoMatchingViewException noView) {
  if (view != null) {
    assertThat(
        "View is present in the hierarchy: " + HumanReadables.describe(view), true, is(false));
  }
}
 
Example #21
Source File: Root.java    From android-test with Apache License 2.0 5 votes vote down vote up
@Override
public String toString() {
  ToStringHelper helper =
      toStringHelper(this)
          .add("application-window-token", decorView.getApplicationWindowToken())
          .add("window-token", decorView.getWindowToken())
          .add("has-window-focus", decorView.hasWindowFocus());
  if (windowLayoutParams.isPresent()) {
    helper
        .add("layout-params-type", windowLayoutParams.get().type)
        .add("layout-params-string", windowLayoutParams.get());
  }
  helper.add("decor-view-string", HumanReadables.describe(decorView));
  return helper.toString();
}
 
Example #22
Source File: RecyclerViewActions.java    From android-test with Apache License 2.0 5 votes vote down vote up
/**
 * Finds positions of items in {@link RecyclerView} which is matching given viewHolderMatcher.
 * This is similar to positionMatching(RecyclerView, Matcher<VH>), except that it returns list of
 * multiple positions if there are, rather than throwing Ambiguous view error exception.
 *
 * @param recyclerView recycler view which is hosting items.
 * @param viewHolderMatcher a <a
 *     href="http://hamcrest.org/JavaHamcrest/javadoc/1.3/org/hamcrest/Matcher.html"><code>Matcher
 *     </code></a> that matches an item view in {@link RecyclerView}
 * @return list of MatchedItem which contains position and description of items in recyclerView.
 * @throws RuntimeException if more than one item or item could not be found.
 */
@SuppressWarnings("unchecked")
private static <T extends VH, VH extends ViewHolder> List<MatchedItem> itemsMatching(
    final RecyclerView recyclerView, final Matcher<VH> viewHolderMatcher, int max) {
  final Adapter<T> adapter = recyclerView.getAdapter();
  SparseArray<VH> viewHolderCache = new SparseArray<VH>();
  List<MatchedItem> matchedItems = new ArrayList<MatchedItem>();
  for (int position = 0; position < adapter.getItemCount(); position++) {
    int itemType = adapter.getItemViewType(position);
    VH cachedViewHolder = viewHolderCache.get(itemType);
    // Create a view holder per type if not exists
    if (null == cachedViewHolder) {
      cachedViewHolder = adapter.createViewHolder(recyclerView, itemType);
      viewHolderCache.put(itemType, cachedViewHolder);
    }
    // Bind data to ViewHolder and apply matcher to view descendants.
    adapter.bindViewHolder((T) cachedViewHolder, position);
    if (viewHolderMatcher.matches(cachedViewHolder)) {
      matchedItems.add(
          new MatchedItem(
              position,
              HumanReadables.getViewHierarchyErrorMessage(
                  cachedViewHolder.itemView,
                  null,
                  "\n\n*** Matched ViewHolder item at position: " + position + " ***",
                  null)));
      adapter.onViewRecycled((T) cachedViewHolder);
      if (matchedItems.size() == max) {
        break;
      }
    } else {
      adapter.onViewRecycled((T) cachedViewHolder);
    }
  }
  return matchedItems;
}
 
Example #23
Source File: RecyclerViewActions.java    From android-test with Apache License 2.0 5 votes vote down vote up
@SuppressWarnings("unchecked")
@Override
public void perform(UiController uiController, View view) {
  RecyclerView recyclerView = (RecyclerView) view;
  try {
    int maxMatches = atPosition == NO_POSITION ? 2 : atPosition + 1;
    int selectIndex = atPosition == NO_POSITION ? 0 : atPosition;
    List<MatchedItem> matchedItems = itemsMatching(recyclerView, viewHolderMatcher, maxMatches);

    if (selectIndex >= matchedItems.size()) {
      throw new RuntimeException(
          String.format(
              "Found %d items matching %s, but position %d was requested.",
              matchedItems.size(), viewHolderMatcher.toString(), atPosition));
    }
    if (atPosition == NO_POSITION && matchedItems.size() == 2) {
      StringBuilder ambiguousViewError = new StringBuilder();
      ambiguousViewError.append(
          String.format("Found more than one sub-view matching %s", viewHolderMatcher));
      for (MatchedItem item : matchedItems) {
        ambiguousViewError.append(item + "\n");
      }
      throw new RuntimeException(ambiguousViewError.toString());
    }
    recyclerView.scrollToPosition(matchedItems.get(selectIndex).position);
    uiController.loopMainThreadUntilIdle();
  } catch (RuntimeException e) {
    throw new PerformException.Builder()
        .withActionDescription(this.getDescription())
        .withViewDescription(HumanReadables.describe(view))
        .withCause(e)
        .build();
  }
}
 
Example #24
Source File: RecyclerViewActions.java    From android-test with Apache License 2.0 5 votes vote down vote up
@Override
public void perform(UiController uiController, View view) {
  RecyclerView recyclerView = (RecyclerView) view;

  new ScrollToPositionViewAction(position).perform(uiController, view);
  uiController.loopMainThreadUntilIdle();

  @SuppressWarnings("unchecked")
  VH viewHolderForPosition = (VH) recyclerView.findViewHolderForAdapterPosition(position);
  if (null == viewHolderForPosition) {
    throw new PerformException.Builder()
        .withActionDescription(this.toString())
        .withViewDescription(HumanReadables.describe(view))
        .withCause(new IllegalStateException("No view holder at position: " + position))
        .build();
  }

  View viewAtPosition = viewHolderForPosition.itemView;
  if (null == viewAtPosition) {
    throw new PerformException.Builder()
        .withActionDescription(this.toString())
        .withViewDescription(HumanReadables.describe(viewAtPosition))
        .withCause(new IllegalStateException("No view at position: " + position))
        .build();
  }

  viewAction.perform(uiController, viewAtPosition);
}
 
Example #25
Source File: ViewActions.java    From Kore with Apache License 2.0 5 votes vote down vote up
/**
 * ViewAction that waits until view with viewId becomes visible
 * @param viewId Resource identifier of view item that must be checked
 * @param checkStatus called when viewId has been found to check its status. If return value
 *                      is true waitForView will stop, false it will continue until timeout is exceeded
 * @param millis amount of time to wait for view to become visible
 * @return
 */
public static ViewAction waitForView(final int viewId, final CheckStatus checkStatus, final long millis) {
    return new ViewAction() {
        @Override
        public Matcher<View> getConstraints() {
            return isRoot();
        }

        @Override
        public String getDescription() {
            return "Searches for view with id: " + viewId + " and tests its status using CheckStatus, using timeout " + millis + " ms.";
        }

        @Override
        public void perform(UiController uiController, View view) {
            final long endTime = System.currentTimeMillis() + millis;
            do {
                for (View child : TreeIterables.breadthFirstViewTraversal(view)) {
                    if (child.getId() == viewId) {
                        if (checkStatus.check(child)) {
                            return;
                        }
                    }
                }

                uiController.loopMainThreadForAtLeast(50);
            } while (System.currentTimeMillis() < endTime);

            throw new PerformException.Builder()
                    .withActionDescription(this.getDescription())
                    .withViewDescription(HumanReadables.describe(view))
                    .withCause(new TimeoutException())
                    .build();
        }
    };
}
 
Example #26
Source File: AccessibilityChecks.java    From android-test with Apache License 2.0 4 votes vote down vote up
@Override
public String describeView(View view) {
  return HumanReadables.describe(view);
}
 
Example #27
Source File: AccessibilityChecks.java    From android-test with Apache License 2.0 4 votes vote down vote up
@Override
public String describeView(View view) {
  return HumanReadables.describe(view);
}
 
Example #28
Source File: GeneralSwipeAction.java    From android-test with Apache License 2.0 4 votes vote down vote up
@Override
public void perform(UiController uiController, View view) {
  float[] startCoordinates = startCoordinatesProvider.calculateCoordinates(view);
  float[] endCoordinates = endCoordinatesProvider.calculateCoordinates(view);
  float[] precision = precisionDescriber.describePrecision();

  Swiper.Status status = Swiper.Status.FAILURE;

  for (int tries = 0; tries < MAX_TRIES && status != Swiper.Status.SUCCESS; tries++) {
    try {
      status = swiper.sendSwipe(uiController, startCoordinates, endCoordinates, precision);
    } catch (RuntimeException re) {
      throw new PerformException.Builder()
          .withActionDescription(this.getDescription())
          .withViewDescription(HumanReadables.describe(view))
          .withCause(re)
          .build();
    }

    int duration = ViewConfiguration.getPressedStateDuration();
    // ensures that all work enqueued to process the swipe has been run.
    if (duration > 0) {
      uiController.loopMainThreadForAtLeast(duration);
    }
  }

  if (status == Swiper.Status.FAILURE) {
    throw new PerformException.Builder()
        .withActionDescription(getDescription())
        .withViewDescription(HumanReadables.describe(view))
        .withCause(
            new RuntimeException(
                String.format(
                    Locale.ROOT,
                    "Couldn't swipe from: %s,%s to: %s,%s precision: %s, %s . Swiper: %s "
                        + "start coordinate provider: %s precision describer: %s. Tried %s times",
                    startCoordinates[0],
                    startCoordinates[1],
                    endCoordinates[0],
                    endCoordinates[1],
                    precision[0],
                    precision[1],
                    swiper,
                    startCoordinatesProvider,
                    precisionDescriber,
                    MAX_TRIES)))
        .build();
  }
}
 
Example #29
Source File: Utils.java    From BottomNavigation with Apache License 2.0 4 votes vote down vote up
/**
 * Perform action of waiting for a specific view id.
 */
public static ViewAction waitId(final int viewId, final long millis) {
    return new ViewAction() {
        @Override
        public Matcher<View> getConstraints() {
            return isRoot();
        }

        @Override
        public String getDescription() {
            return "wait for a specific view with id <" + viewId + "> during " + millis + " millis.";
        }

        @Override
        public void perform(final UiController uiController, final View view) {
            uiController.loopMainThreadUntilIdle();
            final long startTime = System.currentTimeMillis();
            final long endTime = startTime + millis;
            final Matcher<View> viewMatcher = withId(viewId);

            do {
                for (View child : TreeIterables.breadthFirstViewTraversal(view)) {
                    // found view with required ID
                    if (viewMatcher.matches(child)) {
                        return;
                    }
                }

                uiController.loopMainThreadForAtLeast(50);
            }
            while (System.currentTimeMillis() < endTime);

            // timeout happens
            throw new PerformException.Builder()
                    .withActionDescription(this.getDescription())
                    .withViewDescription(HumanReadables.describe(view))
                    .withCause(new TimeoutException())
                    .build();
        }
    };
}