View Javadoc
1   package io.guixer.tools;
2   
3   import static com.google.common.base.Preconditions.checkNotNull;
4   import static org.apache.commons.lang3.StringUtils.substringAfter;
5   import static org.apache.commons.lang3.StringUtils.substringBefore;
6   
7   import java.util.List;
8   
9   import org.apache.commons.lang3.NotImplementedException;
10  import org.openqa.selenium.By;
11  import org.openqa.selenium.By.ByClassName;
12  import org.openqa.selenium.By.ByCssSelector;
13  import org.openqa.selenium.By.ById;
14  import org.openqa.selenium.By.ByLinkText;
15  import org.openqa.selenium.By.ByName;
16  import org.openqa.selenium.By.ByTagName;
17  import org.openqa.selenium.By.ByXPath;
18  import org.openqa.selenium.WebDriver;
19  import org.openqa.selenium.WebElement;
20  
21  import io.guixer.tools.dom.DomFinder;
22  import io.guixer.tools.dom.WebDom;
23  import io.guixer.tools.dom.WebDomElement;
24  
25  public abstract class Locators {
26  
27  	public static By by(
28  		final String locator
29  	) {
30  
31  		checkNotNull(locator, "locator");
32  
33  		if (locator.startsWith("#") && !locator.contains(" ") && !locator.contains(".")) {
34  
35  			return By.id(locator.substring(1));
36  
37  		} else if (locator.startsWith("//")) {
38  
39  			return By.xpath(parseContains(locator));
40  
41  		} else if (locator.startsWith("id:")) {
42  
43  			return By.id(substringAfter(locator, ":"));
44  
45  		} else if (locator.startsWith("tagName:") || locator.startsWith("tag:")) {
46  
47  			return By.tagName(substringAfter(locator, ":"));
48  
49  		} else if (locator.startsWith("cssSelector:") || locator.startsWith("css:")) {
50  
51  			return By.cssSelector(substringAfter(locator, ":"));
52  
53  		} else if (locator.startsWith("name:")) {
54  
55  			return By.name(substringAfter(locator, ":"));
56  
57  		} else if (locator.startsWith("linkText:") || locator.startsWith("link:")) {
58  
59  			return By.linkText(substringAfter(locator, ":"));
60  
61  		} else if (locator.startsWith("partialLinkText:") || locator.startsWith("partialLink:")) {
62  
63  			return By.partialLinkText(substringAfter(locator, ":"));
64  
65  		} else if (locator.startsWith("className:") || locator.startsWith("class:")) {
66  
67  			return By.className(substringAfter(locator, ":"));
68  
69  		} else if (locator.startsWith("xpath:")) {
70  
71  			return By.xpath(substringAfter(locator, ":"));
72  
73  		} else if (locator.contains("#") && !locator.contains("= '#")) {
74  
75  			final String tagName = substringBefore(locator, "#");
76  			final String id = substringAfter(locator, "#");
77  
78  			return By.xpath("//" + tagName + "[@id = '" + id + "']");
79  
80  		} else {
81  
82  			return By.xpath("//" + parseContains(locator));
83  		}
84  	}
85  
86  	private static String parseContains(
87  		final String locator
88  	) {
89  
90  		final StringBuilder sb = new StringBuilder();
91  
92  		int offset = 0;
93  
94  		while (true) {
95  
96  			final int index = locator.indexOf("contains(", offset);
97  
98  			if (index == -1) {
99  				break;
100 			}
101 
102 			sb.append(locator.substring(offset, index));
103 
104 			final int end = locator.indexOf(")", index);
105 
106 			if (locator.substring(index, end).contains(",")) {
107 
108 				sb.append(locator.substring(index, end));
109 
110 			} else {
111 
112 				sb.append(locator.substring(index, index + 9) + "., ");
113 
114 				sb.append(locator.substring(index + 9, end));
115 			}
116 
117 			offset = end;
118 		}
119 
120 		sb.append(locator.substring(offset));
121 
122 		return sb.toString();
123 	}
124 
125 	public static String locator(
126 		final By by
127 	) {
128 
129 		checkNotNull(by, "by");
130 
131 		if (by instanceof ById) {
132 
133 			return "#" + substringAfter(by.toString(), " ");
134 
135 		} else if (by instanceof ByXPath) {
136 
137 			return "xpath:" + substringAfter(by.toString(), " ");
138 
139 		} else if (by instanceof ByClassName) {
140 
141 			return "class:" + substringAfter(by.toString(), " ");
142 
143 		} else if (by instanceof ByTagName) {
144 
145 			return "tag:" + substringAfter(by.toString(), " ");
146 
147 		} else if (by instanceof ByCssSelector) {
148 
149 			return "css:" + substringAfter(by.toString(), " ");
150 
151 		} else if (by instanceof ByLinkText) {
152 
153 			return "link:" + substringAfter(by.toString(), " ");
154 
155 		} else if (by instanceof ByName) {
156 
157 			return "name:" + substringAfter(by.toString(), " ");
158 
159 		} else {
160 
161 			throw new NotImplementedException("by: " + by);
162 		}
163 	}
164 
165 	public static String inferLocator(
166 		final WebDriver driver,
167 		final WebElement element
168 	) {
169 
170 		checkNotNull(driver, "driver");
171 		checkNotNull(element, "element");
172 
173 		final By by = DomFinder.inferBy(new WebDom(driver), new WebDomElement(element));
174 
175 		final List<WebElement> elements = driver.findElements(by);
176 
177 		if (elements.size() != 1) {
178 
179 			throw new IllegalStateException("No non-ambiguous locator was found for element: " + by);
180 		}
181 
182 		return locator(by);
183 	}
184 
185 	public static String addQuotesForXPath(
186 		final String s
187 	) {
188 
189 		checkNotNull(s, "s");
190 
191 		final StringBuilder sb = new StringBuilder();
192 
193 		for (int offset = 0;;) {
194 
195 			final int indexOfSingleQuote = s.indexOf('\'', offset);
196 			final int indexOfDoubleQuotes = s.indexOf('"', offset);
197 
198 			if (indexOfSingleQuote == -1) {
199 
200 				if (offset == 0) {
201 
202 					return '\'' + s + '\'';
203 
204 				} else {
205 
206 					return sb.append(", '" + s.substring(offset) + "')").toString();
207 				}
208 
209 			} else if (indexOfDoubleQuotes == -1) {
210 
211 				if (offset == 0) {
212 
213 					return '"' + s + '"';
214 
215 				} else {
216 
217 					return sb.append(", \"" + s.substring(offset) + "\")").toString();
218 				}
219 
220 			} else if (indexOfSingleQuote < indexOfDoubleQuotes) {
221 
222 				final String fragment = s.substring(offset, indexOfDoubleQuotes);
223 
224 				sb.append(sb.isEmpty() ? "concat(" : ", ");
225 
226 				sb.append("\"" + fragment + "\"").toString();
227 
228 				offset = indexOfDoubleQuotes;
229 
230 			} else {
231 
232 				final String fragment = s.substring(offset, indexOfSingleQuote);
233 
234 				sb.append(sb.isEmpty() ? "concat(" : ", ");
235 
236 				sb.append("'" + fragment + "'").toString();
237 
238 				offset = indexOfSingleQuote;
239 			}
240 		}
241 	}
242 }