/** * Create and return a UiSelector based on the strategy, text, and how many you want returned. * * @param strategy The {@link Strategy} used to search for the element. * @param text Any text used in the search (i.e. match, regex, etc.) * @param many Boolean that is either only one element (false), or many (true) * @return UiSelector * @throws InvalidStrategyException * @throws AndroidCommandException */ private UiSelector getSelector(final Strategy strategy, final String text, final Boolean many) throws InvalidStrategyException, AndroidCommandException { UiSelector sel = new UiSelector(); switch (strategy) { case CLASS_NAME: case TAG_NAME: String androidClass = AndroidElementClassMap.match(text); if (androidClass.contentEquals("android.widget.Button")) { androidClass += "|android.widget.ImageButton"; androidClass = androidClass.replaceAll("([^\\p{Alnum}|])", "\\\\$1"); sel = sel.classNameMatches("^" + androidClass + "$"); } else { sel = sel.className(androidClass); } break; case NAME: sel = sel.description(text); break; case XPATH: break; case LINK_TEXT: case PARTIAL_LINK_TEXT: case ID: case CSS_SELECTOR: default: throw new InvalidStrategyException( "Strategy " + strategy.getStrategyName() + " is not valid."); } if (!many) { sel = sel.instance(0); } return sel; }
/** * Create and return a UiSelector based on Xpath attributes. * * @param path The Xpath path. * @param attr The attribute. * @param constraint Any constraint. * @param substr Any substr. * @return UiSelector * @throws AndroidCommandException */ private UiSelector getSelectorForXpath( final JSONArray path, final String attr, String constraint, final boolean substr) throws AndroidCommandException { UiSelector s = new UiSelector(); JSONObject pathObj; String nodeType; String searchType; final String substrStr = substr ? "true" : "false"; Logger.info( "Building xpath selector from attr " + attr + " and constraint " + constraint + " and substr " + substrStr); String selOut = "s"; // $driver.find_element :xpath, %(//*[contains(@text, 'agree')]) // info: [ANDROID] [info] Building xpath selector from attr text and // constraint agree and substr true // info: [ANDROID] [info] s.className('*').textContains('agree') try { nodeType = path.getJSONObject(0).getString("node"); } catch (final JSONException e) { throw new AndroidCommandException("Error parsing xpath path obj from JSON"); } if (attr.toLowerCase().contentEquals("text") && !constraint.isEmpty() && substr == true && nodeType.contentEquals("*") == true) { selOut += ".textContains('" + constraint + "')"; s = s.textContains(constraint); Logger.info(selOut); return s; } // //*[contains(@tag, "button")] if (attr.toLowerCase().contentEquals("tag") && !constraint.isEmpty() && substr == true && nodeType.contentEquals("*") == true) { // (?i) = case insensitive match. Esape everything that isn't an // alpha num. // use .* to match on contains. constraint = "(?i)^.*" + constraint.replaceAll("([^\\p{Alnum}])", "\\\\$1") + ".*$"; selOut += ".classNameMatches('" + constraint + "')"; s = s.classNameMatches(constraint); Logger.info(selOut); return s; } for (int i = 0; i < path.length(); i++) { try { pathObj = path.getJSONObject(i); nodeType = pathObj.getString("node"); searchType = pathObj.getString("search"); } catch (final JSONException e) { throw new AndroidCommandException("Error parsing xpath path obj from JSON"); } nodeType = AndroidElementClassMap.match(nodeType); if (searchType.equals("child")) { s = s.childSelector(s); selOut += ".childSelector(s)"; } else { s = s.className(nodeType); selOut += ".className('" + nodeType + "')"; } } if (attr.equals("desc") || attr.equals("name")) { selOut += ".description"; if (substr) { selOut += "Contains"; s = s.descriptionContains(constraint); } else { s = s.description(constraint); } selOut += "('" + constraint + "')"; } else if (attr.equals("text") || attr.equals("value")) { selOut += ".text"; if (substr) { selOut += "Contains"; s = s.textContains(constraint); } else { s = s.text(constraint); } selOut += "('" + constraint + "')"; } Logger.info(selOut); return s; }