import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import net.sf.sahi.client.Browser; import net.sf.sahi.client.ElementStub; public class JQuery { protected Browser browser; public JQuery(Browser browser){ this.browser = browser; } private String[] getMatches(String text, String regex){ List allMatches = new ArrayList(); Matcher m = Pattern.compile(regex) .matcher(text); while (m.find()) { allMatches.add(m.group()); } allMatches.add(0, " "); return allMatches.toArray(new String[allMatches.size()]); } public ElementStub get(String dsl){ return get(dsl, false); } public ElementStub get(String dsl, Boolean forceXPath){ dsl = dsl.replaceAll("\\s+(?=[^\\{\\}]*\\})", "-^v^v^-"); //Using a delimiter for space inside curly braces - "{Products Tab}" String delimiterRegex = "\\s+>?\\s+|\\s+"; // the selector is split based on " " and " > " if(dsl.matches("\\s+>\\s+|\\s+")) // Return XPath if " > " is present forceXPath = true; String keys[] = dsl.split(delimiterRegex); String delimiters[] = this.getMatches(dsl, delimiterRegex); for(int i = 0; i < keys.length; i++) keys[i] = keys[i].replace("-^v^v^-", " "); Boolean xPathFlag = forceXPath; String xPath = ""; ElementStub el = null; for(int i = 0; i < keys.length; i++){ if(!xPathFlag){ ElementStub ret = this.getSingleElement(keys[i].trim()); if(ret == null) xPathFlag = true; else if(el == null) el = ret; else el = ret.in(el); } xPath += addXPath(keys[i].trim(), delimiters[i].trim()); } if(xPathFlag || el == null) return this.browser.byXPath(xPath); return el; } private String addXPath(String selector, String delimiter) { int hash = selector.indexOf('#'); int dot = selector.indexOf('.'); int textOpen = selector.indexOf('{'); String path = ""; String text = ""; delimiter = delimiter.equals(">") ? "/" : "//"; int index = -1; if (selector.contains("[") && selector.contains("]")){ // Removing the text from string before checking for '.' and '#' index = Integer.parseInt(selector.substring(selector.indexOf('[') + 1, selector.indexOf(']'))); selector = selector.substring(0, selector.indexOf('[')); } if (selector.contains("{") && selector.contains("}")){ // Removing the text from string before checking for '.' and '#' text = selector.substring(textOpen + 1, selector.indexOf('}')); selector = selector.substring(0, textOpen); } if(selector.contains("#")){ // By Id String id = ""; if(dot != -1) id = selector.substring(hash + 1, dot); else id = selector.substring(hash + 1); path = delimiter + "*[@id='" + id + "']"; } else if(selector.contains(".")){ // By Class Name int lastDot = selector.lastIndexOf('.'); String tagName = "*"; if(dot != 0) tagName = selector.substring(0, dot); path = delimiter + tagName; String[] classNames = selector.split("\\."); for(int i = 1; i < classNames.length; i++) path += "[contains(@class, '" + classNames[i] + "')]"; } else if (text.length() > 0){ // By text - Syntax: "{some text}" String tagName = "*"; if(textOpen != 0) tagName = selector; path = delimiter + tagName + "[text()[contains(.,'" + text + "')]]"; } else { //Default - tagname path = delimiter + selector; } if(index > -1) path = path + "[" + index + "]"; return path; } private ElementStub getSingleElement(String selector) { int hash = selector.indexOf('#'); int dot = selector.indexOf('.'); int textOpen = selector.indexOf('{'); String text = ""; int index = -1; if (selector.contains("[") && selector.contains("]")){ // Removing the text from string before checking for '.' and '#' index = Integer.parseInt(selector.substring(selector.indexOf('[') + 1, selector.indexOf(']'))); selector = selector.substring(0, selector.indexOf('[')); } if (selector.contains("{") && selector.contains("}")){ // Removing the text from string before checking for '.' and '#' text = selector.substring(textOpen + 1, selector.indexOf('}')); selector = selector.substring(0, textOpen); } if(selector.contains("#")){ // By Id String id = ""; if(dot != -1) id = selector.substring(hash + 1, dot); else id = selector.substring(hash + 1); return this.browser.byId(id); } else if(selector.contains(".")){ // By Class Name // Need to improvise for multiple classes int lastDot = selector.lastIndexOf('.'); String className = ""; if (lastDot != dot && lastDot != -1) className = selector.substring(dot + 1, lastDot); else className = selector.substring(dot + 1); if(dot != 0){ String tagName = selector.substring(0, dot); return this.browser.byClassName("/" + className + "/", tagName); } return null; } else if (text.length() > 0){ // By text - Syntax: "{some text}" String tagName = selector; if(textOpen != 0) return this.browser.byText(text, tagName); return null; } // Tag names else if(index > -1){ if(selector.equalsIgnoreCase("button")) return this.browser.button(index); else if(selector.equalsIgnoreCase("checkbox")) return this.browser.checkbox(index); else if(selector.equalsIgnoreCase("div")) return this.browser.div(index); else if(selector.equalsIgnoreCase("h1")) return this.browser.heading1(index); else if(selector.equalsIgnoreCase("h2")) return this.browser.heading2(index); else if(selector.equalsIgnoreCase("h3")) return this.browser.heading3(index); else if(selector.equalsIgnoreCase("h4")) return this.browser.heading4(index); else if(selector.equalsIgnoreCase("h5")) return this.browser.heading5(index); else if(selector.equalsIgnoreCase("h6")) return this.browser.heading6(index); else if(selector.equalsIgnoreCase("img")) return this.browser.image(index); else if(selector.equalsIgnoreCase("a")) return this.browser.link(index); else if(selector.equalsIgnoreCase("li")) return this.browser.listItem(index); else if(selector.equalsIgnoreCase("ul") || selector.equalsIgnoreCase("ol")) return this.browser.list(index); else if(selector.equalsIgnoreCase("option")) return this.browser.option(index); else if(selector.equalsIgnoreCase("p")) return this.browser.paragraph(index); else if(selector.equalsIgnoreCase("password")) return this.browser.password(index); else if(selector.equalsIgnoreCase("radio")) return this.browser.radio(index); else if(selector.equalsIgnoreCase("table")) return this.browser.table(index); else if(selector.equalsIgnoreCase("select")) return this.browser.select(index); else if(selector.equalsIgnoreCase("span")) return this.browser.span(index); else if(selector.equalsIgnoreCase("submit")) return this.browser.submit(index); else if(selector.equalsIgnoreCase("textbox")) return this.browser.textbox(index); return browser.div(selector + "[" + index + "]"); } return null; } }