From f45db0f1ebd13f3f61da3f1ce012761d05ebbeb1 Mon Sep 17 00:00:00 2001 From: Sravan Medrapu Date: Tue, 20 Dec 2016 19:05:36 +0530 Subject: [PATCH 1/2] Refactored XPATHFinder to include special characters($) in className prop --- .../uiautomator2/model/XPathFinder.java | 40 ++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/io/appium/uiautomator2/model/XPathFinder.java b/app/src/main/java/io/appium/uiautomator2/model/XPathFinder.java index 0163ca3e0..4a27a8e25 100644 --- a/app/src/main/java/io/appium/uiautomator2/model/XPathFinder.java +++ b/app/src/main/java/io/appium/uiautomator2/model/XPathFinder.java @@ -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; @@ -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()); @@ -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); + } } From 4e1687c0cd7b53423d680818569c4edd14c837bb Mon Sep 17 00:00:00 2001 From: Sravan Medrapu Date: Tue, 20 Dec 2016 19:07:01 +0530 Subject: [PATCH 2/2] Refactored tests to pass in different screen sizes --- .../unittest/test/HandlersTest.java | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/app/src/androidTestE2eTest/java/io/appium/uiautomator2/unittest/test/HandlersTest.java b/app/src/androidTestE2eTest/java/io/appium/uiautomator2/unittest/test/HandlersTest.java index 3dc6fdc94..95e8ab587 100644 --- a/app/src/androidTestE2eTest/java/io/appium/uiautomator2/unittest/test/HandlersTest.java +++ b/app/src/androidTestE2eTest/java/io/appium/uiautomator2/unittest/test/HandlersTest.java @@ -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(" @@ -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").read(response)); } @@ -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"); @@ -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);