View Javadoc
1   package net.avcompris.guixer.core;
2   
3   import static com.google.common.base.Preconditions.checkNotNull;
4   import static net.avcompris.guixer.core.Validations.assertValidLabel;
5   import static org.apache.commons.lang3.StringUtils.normalizeSpace;
6   import static org.apache.commons.lang3.StringUtils.split;
7   import static org.junit.jupiter.api.Assertions.assertFalse;
8   import static org.junit.jupiter.api.Assertions.assertTrue;
9   import static org.openqa.selenium.support.ui.ExpectedConditions.presenceOfElementLocated;
10  import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;
11  
12  import java.io.File;
13  import java.io.IOException;
14  
15  import javax.annotation.Nullable;
16  
17  import org.apache.commons.io.FileUtils;
18  import org.apache.commons.lang3.ArrayUtils;
19  import org.openqa.selenium.OutputType;
20  import org.openqa.selenium.TakesScreenshot;
21  import org.openqa.selenium.WebDriver;
22  import org.openqa.selenium.WebDriverException;
23  import org.openqa.selenium.WebElement;
24  import org.openqa.selenium.support.ui.Select;
25  import org.openqa.selenium.support.ui.WebDriverWait;
26  
27  final class CommandSeleniumImpl implements Command {
28  
29  	private final WebDriver driver;
30  	private final String baseURL;
31  	private final Context context;
32  
33  	public CommandSeleniumImpl( //
34  			final WebDriver driver, //
35  			final String baseURL, //
36  			final Context context) {
37  
38  		this.driver = checkNotNull(driver, "driver");
39  		this.baseURL = checkNotNull(baseURL, "baseURL");
40  		this.context = checkNotNull(context, "context");
41  	}
42  
43  	@Override
44  	public Command waitFor(final String locator) {
45  
46  		return waitFor(locator, 10);
47  	}
48  
49  	@Override
50  	public Command waitFor(final String locator, final int timeOutSeconds) {
51  
52  		checkNotNull(locator, "locator");
53  
54  		final WebDriverWait wait = new WebDriverWait(driver, timeOutSeconds);
55  
56  		wait.until(presenceOfElementLocated(LocatorUtils.by(locator)));
57  
58  		return this;
59  	}
60  
61  	@Override
62  	public Command waitForVisible(final String locator) {
63  
64  		return waitForVisible(locator, 10);
65  	}
66  
67  	@Override
68  	public Command waitForVisible(final String locator, final int timeOutSeconds) {
69  
70  		checkNotNull(locator, "locator");
71  
72  		final WebDriverWait wait = new WebDriverWait(driver, timeOutSeconds);
73  
74  		wait.until(visibilityOfElementLocated(LocatorUtils.by(locator)));
75  
76  		return this;
77  	}
78  
79  	@Override
80  	public Command sleep(final int ms) {
81  
82  		try {
83  
84  			Thread.sleep(ms);
85  
86  		} catch (final InterruptedException e) {
87  
88  			throw new RuntimeException(e);
89  		}
90  
91  		return this;
92  	}
93  
94  	@Override
95  	public Command takeScreenshot() throws IOException {
96  
97  		return takeScreenshotWithSuffix(".png");
98  	}
99  
100 	private Command takeScreenshotWithSuffix(final String suffix) throws IOException {
101 
102 		context.incStepCount();
103 
104 		final File file;
105 
106 		try {
107 
108 			file = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
109 
110 		} catch (final WebDriverException e) {
111 
112 			e.printStackTrace();
113 
114 			throw e;
115 		}
116 
117 		final File testDir = context.getSubDir();
118 
119 		FileUtils.copyFile(file, new File(testDir, context.formatStepCount() + suffix));
120 
121 		return this;
122 	}
123 
124 	@Override
125 	public Command takeScreenshot(final String label) throws IOException {
126 
127 		assertValidLabel(label);
128 
129 		return takeScreenshotWithSuffix("-" + label + ".png");
130 	}
131 
132 	@Override
133 	public Command get() {
134 
135 		driver.get(baseURL);
136 
137 		return this;
138 	}
139 
140 	@Override
141 	public SwitchTo switchTo() {
142 
143 		return new SwitchToSeleniumImpl( //
144 				driver.switchTo(), //
145 				this);
146 	}
147 
148 	@Override
149 	public Command log(@Nullable final String text) {
150 
151 		// do nothing
152 
153 		return this;
154 	}
155 
156 	private WebElement findElement(final String locator) {
157 
158 		return driver.findElement(LocatorUtils.by(locator));
159 	}
160 
161 	@Override
162 	public Command clear(final String locator) {
163 
164 		findElement(locator).clear();
165 
166 		return this;
167 	}
168 
169 	@Override
170 	public Command click(final String locator) {
171 
172 		findElement(locator).click();
173 
174 		return this;
175 	}
176 
177 	@Override
178 	public Command submit(final String locator) {
179 
180 		findElement(locator).submit();
181 
182 		return this;
183 	}
184 
185 	@Override
186 	public Command assertHasClass(final String locator, final String className) {
187 
188 		return wrapAssertion(locator, className, () -> {
189 
190 			final String classNames = findElement(locator).getAttribute("class");
191 
192 			final String normalizedClassNames = normalizeSpace(classNames);
193 
194 			assertTrue(ArrayUtils.contains(split(normalizedClassNames, " "), className),
195 					"Classes should include: " + className + ", but was: " + normalizedClassNames);
196 		});
197 	}
198 
199 	@Override
200 	public Command assertDoesntHaveClass(final String locator, final String className) {
201 
202 		return wrapAssertion(locator, className, () -> {
203 
204 			final String classNames = findElement(locator).getAttribute("class");
205 
206 			final String normalizedClassNames = normalizeSpace(classNames);
207 
208 			assertFalse(ArrayUtils.contains(split(normalizedClassNames, " "), className),
209 					"Classes should not include: " + className + ", but was: " + normalizedClassNames);
210 		});
211 	}
212 
213 	private Command wrapAssertion(final String arg0, final String arg1, final Runnable runnable) {
214 
215 		final String assertionName = extractAssertMethodName();
216 
217 		final Assertionn.html#Assertion">Assertion assertion = new Assertion(assertionName, arg0, arg1);
218 
219 		context.addAssertion(assertion);
220 
221 		try {
222 
223 			runnable.run();
224 
225 			assertion.setSuccess();
226 
227 		} catch (final RuntimeException | Error e) {
228 
229 			e.printStackTrace();
230 
231 			assertion.setException(e);
232 		}
233 
234 		return this;
235 	}
236 
237 	private static String extractAssertMethodName() {
238 
239 		for (final StackTraceElement ste : Thread.currentThread().getStackTrace()) {
240 
241 			final String methodName = ste.getMethodName();
242 
243 			if (methodName.startsWith("assert")) {
244 
245 				return methodName;
246 			}
247 		}
248 
249 		throw new IllegalStateException("Cannot extract assertMethodName");
250 	}
251 
252 	@Override
253 	public Command sendKeys(final String locator, final CharSequence... keys) {
254 
255 		findElement(locator).sendKeys(keys);
256 
257 		return this;
258 	}
259 
260 	@Override
261 	public Command sendKeysSecret(final String locator, final String secret) {
262 
263 		findElement(locator).sendKeys(secret);
264 
265 		return this;
266 	}
267 
268 	@Override
269 	public Command select(final String location, final int value) throws IOException {
270 
271 		return select(location, Integer.toString(value));
272 	}
273 
274 	@Override
275 	public Command select(final String location, final String value) throws IOException {
276 
277 		final Select select = new Select(findElement(location));
278 
279 		select.selectByValue(value);
280 
281 		return this;
282 	}
283 
284 	@Override
285 	public Command skip() throws IOException {
286 
287 		throw new IllegalStateException();
288 	}
289 
290 	@Override
291 	public Command when(final String label, final boolean condition) throws IOException {
292 
293 		throw new IllegalStateException();
294 	}
295 
296 	@Override
297 	public Command when(final boolean condition) throws IOException {
298 
299 		throw new IllegalStateException();
300 	}
301 }