blob: 698a915e99d26d94f6efcd37caf8a34073b656d7 [file] [log] [blame]
/*
* Copyright (C) 2013 DroidDriver committers
*
* 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 io.appium.droiddriver.finders;
import android.util.Log;
import io.appium.droiddriver.UiElement;
import io.appium.droiddriver.exceptions.ElementNotFoundException;
import io.appium.droiddriver.util.Logs;
/**
* Traverses the UiElement tree and returns the first UiElement satisfying
* {@link #predicate}.
*/
public class MatchFinder implements Finder {
protected final Predicate<? super UiElement> predicate;
public MatchFinder(Predicate<? super UiElement> predicate) {
if (predicate == null) {
this.predicate = Predicates.any();
} else {
this.predicate = predicate;
}
}
@Override
public String toString() {
return predicate.toString();
}
@Override
public UiElement find(UiElement context) {
if (matches(context)) {
Logs.log(Log.INFO, "Found match: " + context);
return context;
}
for (UiElement child : context.getChildren(UiElement.VISIBLE)) {
try {
return find(child);
} catch (ElementNotFoundException enfe) {
// Do nothing. Continue searching.
}
}
throw new ElementNotFoundException(this);
}
/**
* Returns true if the {@code element} matches this finder. This can be used
* to test the exact match of {@code element} when this finder is used in
* {@link By#anyOf(MatchFinder...)}.
*
* @param element The element to validate against
* @return true if the element matches
*/
public final boolean matches(UiElement element) {
return predicate.apply(element);
}
}