Skip to content

Commit

Permalink
Merge pull request #45 from sravanmedarapu/master
Browse files Browse the repository at this point in the history
Clasname with special characters issue
  • Loading branch information
sravanmedarapu authored Dec 22, 2016
2 parents 18b71dd + 4e1687c commit 51f0944
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ public void findElementUsingUiAutomatorTest() throws JSONException {
waitForElement(By.xpath("//*[@text='API Demos']"), 5 * SECOND);
scrollTo("Views"); // Due to 'Views' option not visible on small screen
click(findElement(By.accessibilityId("Views")));
waitForElement(By.accessibilityId("Animation"), 10 * SECOND);

By androidUiAutomator = By.androidUiAutomator("new UiScrollable(new UiSelector()"
+ ".resourceId(\"android:id/list\")).scrollIntoView("
Expand Down Expand Up @@ -417,6 +418,7 @@ public void flickOnElementTest() throws JSONException {
waitForElement(By.id("android:id/text1"), 5 * SECOND);
response = flickOnElement(findElement(By.id("android:id/text1")));
getUiDevice().waitForIdle();
waitForElement(By.accessibilityId("Custom View"), 10 * SECOND);
assertTrue(JsonPath.compile("$.value").<Boolean>read(response));
}

Expand Down Expand Up @@ -766,16 +768,16 @@ public void findElementWithContextId() throws JSONException {
@Test
public void findElementWithAttributes() throws JSONException {
waitForElement(By.xpath("//*[@text='API Demos']"), 5 * SECOND);
waitForElement(By.accessibilityId("Views"), 10 * SECOND);
scrollTo("Views");
click(findElement(By.accessibilityId("Views")));
element = findElement(By.xpath("//*[@enabled='true' and @scrollable='true']"));
Logger.info("[AppiumUiAutomator2Server]", " findElement By.androidUiAutomator: " + element);
assertTrue("//*[@enabled='true' and @scrollable='true'] not found", isElementPresent(element));
waitForElement(By.accessibilityId("Focus"), 10 * SECOND);
getUiDevice().waitForIdle();

result = getAttribute(element, "selected");
assertEquals(false, (Boolean)getValueInJsonObject(result, "value"));
element = findElement(By.accessibilityId("Focus"));
Logger.info("[AppiumUiAutomator2Server]", " findElement By.accessibilityId: " + element);
assertTrue("By.accessibilityId(\"Focus\") not found", isElementPresent(element));

result = getAttribute(element, "scrollable");
result = getAttribute(element, "clickable");
assertEquals(true, (Boolean)getValueInJsonObject(result, "value"));

result = getAttribute(element, "enabled");
Expand All @@ -795,7 +797,7 @@ public void findElementWithClassName() throws JSONException {
public void findElementWithIndex() throws JSONException {
//using index attribute on xpath
waitForElement(By.xpath("//*[@text='API Demos']"), 5 * SECOND);
element = findElement(By.xpath("//android.widget.FrameLayout[@index='0']//android.view.ViewGroup[@index='0']//android.widget.FrameLayout[@index='0']//android.view.ViewGroup[@index='0']//android.widget.TextView[@index='0']"));
element = findElement(By.xpath("//android.widget.FrameLayout[@index='0']//android.widget.TextView[@index='0']"));
Logger.debug("[AppiumUiAutomator2Server]", " findElement By.xpath: " + element);
String elementTxt = getText(element);
assertEquals("API Demos", elementTxt);
Expand Down
40 changes: 39 additions & 1 deletion app/src/main/java/io/appium/uiautomator2/model/XPathFinder.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

Expand Down Expand Up @@ -142,15 +143,36 @@ private static Element getDomNode(UiElement<?, ?> uiElement) {
return domNode;
}

private static void setNodeLocalName(Element element, String className) {
try {
Field localName = element.getClass().getDeclaredField("localName");
localName.setAccessible(true);
localName.set(element, tag(className));
} catch (NoSuchFieldException e) {
Logger.error("Unable to set field localName:"+e.getMessage());
} catch (IllegalAccessException e) {
Logger.error("Unable to set field localName:"+e.getMessage());
}
}

private static Element buildDomNode(UiElement<?, ?> uiElement) {
String className = uiElement.getClassName();
if (className == null) {
className = "UNKNOWN";
}
Element element = getDocument().createElement(tag(className));
Element element = getDocument().createElement(simpleClassName(className));
TO_DOM_MAP.put(uiElement, element);
FROM_DOM_MAP.put(element, uiElement);

/**
* Setting the Element's className field.
* Reason for setting className field in Element object explicitly,
* className property might contain special characters like '$' if it is a Inner class and
* just not possible to create Element object with special characters.
* But Appium should consider Inner classes i.e special characters should be included.
*/
setNodeLocalName(element, className);

setAttribute(element, Attribute.INDEX, String.valueOf(uiElement.getIndex()));
setAttribute(element, Attribute.CLASS, className);
setAttribute(element, Attribute.RESOURCE_ID, uiElement.getResourceId());
Expand Down Expand Up @@ -238,4 +260,20 @@ public static String tag(String className) {
className = className.replaceAll("\\$[0-9]+", "\\$");
return className;
}

/**
* returns by excluding inner class name.
*/
private static String simpleClassName(String name) {
name = name.replaceAll("\\$[0-9]+", "\\$");
// we want the index of the inner class
int start = name.lastIndexOf('$');

// if this isn't an inner class, just find the start of the
// top level class name.
if (start == -1) {
return name;
}
return name.substring(0, start);
}
}

0 comments on commit 51f0944

Please sign in to comment.