Spectatio supports hasAncestor from UI Automator
Test: Locally
Bug: 280643782
Change-Id: I5f8dfe374db403b9dac24d3717b50a341550a9d7
diff --git a/libraries/app-helpers/spectatio/spectatio-util/src/android/platform/spectatio/configs/UiElement.java b/libraries/app-helpers/spectatio/spectatio-util/src/android/platform/spectatio/configs/UiElement.java
index 6cc5133..980506a 100644
--- a/libraries/app-helpers/spectatio/spectatio-util/src/android/platform/spectatio/configs/UiElement.java
+++ b/libraries/app-helpers/spectatio/spectatio-util/src/android/platform/spectatio/configs/UiElement.java
@@ -59,7 +59,11 @@
@SerializedName("SPECIFIERS")
private List<UiElement> mSpecifiers;
- // The specifier for the child of a HAS_CHILD specifier
+ // The specifier for the parent of a HAS_ASCENDANT specifier
+ @SerializedName("ANCESTOR")
+ private UiElement mAncestor;
+
+ // The specifier for the child of a HAS_DESCENDANT specifier
@SerializedName("DESCENDANT")
private UiElement mDescendant;
@@ -79,9 +83,19 @@
mSpecifiers = specifiers;
}
- public UiElement(String type, UiElement descendant, int maxDepth) {
+ public UiElement(String type, UiElement relative, int maxDepth) {
mType = type;
- mDescendant = descendant;
+ switch (type) {
+ case JsonConfigConstants.HAS_DESCENDANT:
+ mDescendant = relative;
+ break;
+ case JsonConfigConstants.HAS_ANCESTOR:
+ mAncestor = relative;
+ break;
+ default:
+ throw new RuntimeException(
+ "Unrecognized type given to UiElement constructor with relative argument");
+ }
mMaxDepth = maxDepth;
}
@@ -119,6 +133,8 @@
return By.clazz(mPackage, mValue);
}
return By.clazz(mValue);
+ case JsonConfigConstants.HAS_ANCESTOR:
+ return By.hasAncestor(mAncestor.getBySelectorForUiElement(), mMaxDepth);
case JsonConfigConstants.HAS_DESCENDANT:
return By.hasDescendant(mDescendant.getBySelectorForUiElement(), mMaxDepth);
case JsonConfigConstants.MULTIPLE:
@@ -165,6 +181,8 @@
}
s.clazz(mValue);
break;
+ case JsonConfigConstants.HAS_ANCESTOR:
+ s.hasAncestor(mAncestor.getBySelectorForUiElement(), mMaxDepth);
case JsonConfigConstants.HAS_DESCENDANT:
s.hasDescendant(mDescendant.getBySelectorForUiElement(), mMaxDepth);
break;
diff --git a/libraries/app-helpers/spectatio/spectatio-util/src/android/platform/spectatio/configs/validators/ValidateUiElement.java b/libraries/app-helpers/spectatio/spectatio-util/src/android/platform/spectatio/configs/validators/ValidateUiElement.java
index c695400..563e8d4 100644
--- a/libraries/app-helpers/spectatio/spectatio-util/src/android/platform/spectatio/configs/validators/ValidateUiElement.java
+++ b/libraries/app-helpers/spectatio/spectatio-util/src/android/platform/spectatio/configs/validators/ValidateUiElement.java
@@ -30,7 +30,6 @@
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;
-import java.util.stream.Collectors;
/**
* {@link ValidateUiElement} is a deserializer that validates Ui Elements in Spectatio JSON Config
@@ -48,6 +47,7 @@
JsonConfigConstants.TEXT_CONTAINS,
JsonConfigConstants.DESCRIPTION,
JsonConfigConstants.CLASS,
+ JsonConfigConstants.HAS_ANCESTOR,
JsonConfigConstants.HAS_DESCENDANT,
JsonConfigConstants.MULTIPLE,
JsonConfigConstants.RESOURCE_ID);
@@ -59,6 +59,7 @@
JsonConfigConstants.PACKAGE,
JsonConfigConstants.FLAG,
JsonConfigConstants.MAX_DEPTH,
+ JsonConfigConstants.ANCESTOR,
JsonConfigConstants.DESCENDANT,
JsonConfigConstants.SPECIFIERS);
@@ -88,15 +89,34 @@
specifiersJson.asList().stream()
.map(element -> context.<UiElement>deserialize(element, typeOfT))
.toList();
+
+ int ancestorSpecifiers = 0;
for (UiElement specifier : specifiers) {
if (JsonConfigConstants.MULTIPLE.equals(specifier.getType())) {
throw new RuntimeException(
"Multiple-specifier can't contain a multiple-specifier.");
}
+ if (JsonConfigConstants.HAS_ANCESTOR.equals(specifier.getType())) {
+ ancestorSpecifiers++;
+ if (ancestorSpecifiers > 1) {
+ throw new RuntimeException(
+ "Multiple-specifier can't contain more than one ancestor "
+ + "specifier.");
+ }
+ }
}
return new UiElement(specifiers);
}
+ if (JsonConfigConstants.HAS_ANCESTOR.equals(type)) {
+ JsonObject parent = validateAndGetObject(JsonConfigConstants.ANCESTOR, jsonObject);
+ int maxDepth = validateAndGetInteger(JsonConfigConstants.MAX_DEPTH, jsonObject, 1);
+ return new UiElement(
+ JsonConfigConstants.HAS_ANCESTOR,
+ context.deserialize(parent, typeOfT),
+ maxDepth);
+ }
+
if (JsonConfigConstants.HAS_DESCENDANT.equals(type)) {
JsonObject childJson = validateAndGetObject(JsonConfigConstants.DESCENDANT, jsonObject);
int maxDepth = validateAndGetInteger(JsonConfigConstants.MAX_DEPTH, jsonObject, 1);
@@ -236,7 +256,7 @@
String.format(
"UI Element TYPE %s in Spectatio JSON Config is invalid. Supported"
+ " Types: [ RESOURCE_ID, TEXT, TEXT_CONTAINS, DESCRIPTION, CLASS,"
- + " MULTIPLE ]",
+ + " MULTIPLE, HAS_ANCESTOR, HAS_DESCENDANT ]",
type));
}
}
@@ -247,13 +267,12 @@
.map(Entry::getKey)
.map(String::trim)
.filter(key -> !mSupportedProperties.contains(key))
- .collect(Collectors.toList());
+ .toList();
if (!unknownProperties.isEmpty()) {
throw new RuntimeException(
String.format(
"Unknown properties: [ %s ] for %s in Spectatio JSON Config",
- unknownProperties.stream().collect(Collectors.joining(", ")),
- jsonObject));
+ String.join(", ", unknownProperties), jsonObject));
}
}
}
diff --git a/libraries/app-helpers/spectatio/spectatio-util/src/android/platform/spectatio/constants/JsonConfigConstants.java b/libraries/app-helpers/spectatio/spectatio-util/src/android/platform/spectatio/constants/JsonConfigConstants.java
index 845caa3..75c9833 100644
--- a/libraries/app-helpers/spectatio/spectatio-util/src/android/platform/spectatio/constants/JsonConfigConstants.java
+++ b/libraries/app-helpers/spectatio/spectatio-util/src/android/platform/spectatio/constants/JsonConfigConstants.java
@@ -29,6 +29,7 @@
public static final String VALUE = "VALUE";
public static final String FLAG = "FLAG";
public static final String PACKAGE = "PACKAGE";
+ public static final String ANCESTOR = "ANCESTOR";
public static final String DESCENDANT = "DESCENDANT";
public static final String MAX_DEPTH = "MAX_DEPTH";
public static final String SPECIFIERS = "SPECIFIERS";
@@ -40,6 +41,7 @@
public static final String TEXT_CONTAINS = "TEXT_CONTAINS";
public static final String DESCRIPTION = "DESCRIPTION";
public static final String CLASS = "CLASS";
+ public static final String HAS_ANCESTOR = "HAS_ANCESTOR";
public static final String HAS_DESCENDANT = "HAS_DESCENDANT";
public static final String MULTIPLE = "MULTIPLE";