1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.testtools.selenium;
17
18 import com.saucelabs.common.SauceOnDemandAuthentication;
19 import com.saucelabs.common.SauceOnDemandSessionIdProvider;
20 import com.saucelabs.junit.SauceOnDemandTestWatcher;
21 import com.saucelabs.saucerest.SauceREST;
22 import org.junit.Assert;
23 import org.openqa.selenium.Platform;
24 import org.openqa.selenium.WebDriver;
25 import org.openqa.selenium.ie.InternetExplorerDriver;
26 import org.openqa.selenium.remote.DesiredCapabilities;
27 import org.openqa.selenium.remote.RemoteWebDriver;
28
29 import java.io.BufferedWriter;
30 import java.io.File;
31 import java.io.FileWriter;
32 import java.io.IOException;
33 import java.net.URL;
34 import java.util.HashMap;
35 import java.util.Map;
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81 public class SauceLabsWebDriverHelper implements SauceOnDemandSessionIdProvider {
82
83
84
85
86
87
88
89
90
91
92
93 public static final String REMOTE_DRIVER_SAUCELABS_PROPERTY = "remote.driver.saucelabs";
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113 public static final String SAUCE_BROWSER_PROPERTY = "saucelabs.browser";
114
115
116
117
118
119
120
121
122 public static final String SAUCE_BUILD_PROPERTY = "rice.version";
123
124
125
126
127
128
129
130
131
132
133
134 public static final String SAUCE_DOWNLOAD_SCRIPT_PROPERTY = "saucelabs.download.scripts";
135
136
137
138
139
140
141
142
143 public static final String SAUCE_IDLE_TIMEOUT_SECONDS_PROPERTY = "saucelabs.idle.timeout.seconds";
144
145
146
147
148
149
150
151
152 public static final String SAUCE_KEY_PROPERTY = "saucelabs.key";
153
154
155
156
157
158
159
160
161 public static final String SAUCE_MAX_DURATION_SECONDS_PROPERTY = "saucelabs.max.duration.seconds";
162
163
164
165
166
167
168
169
170
171
172 public static final String SAUCE_PLATFORM_PROPERTY = "saucelabs.platform";
173
174
175
176
177
178
179
180
181
182
183 public static final String SAUCE_IE_INTRODUCE_FLAKINESS_BY_IGNORING_SECURITY_DOMAINS_PROPERTY = "saucelabs.ie.ignore.domains";
184
185
186
187
188
189
190
191
192
193
194 public static final String SAUCE_POPUP_PROPERTY = "saucelabs.pop.disable";
195
196
197
198
199
200
201
202
203
204
205 public static final String SAUCE_SHARE_PROPERTY = "saucelabs.share";
206
207
208
209
210
211
212
213
214 public static final String SAUCE_USER_PROPERTY = "saucelabs.user";
215
216
217
218
219
220
221
222
223
224
225
226 public static final String SAUCE_VERSION_PROPERTY = "saucelabs.browser.version";
227
228
229
230
231
232
233
234
235 public static final String SAUCE_REST_API_DELAY_MS = "saucelabs.rest.api.delay.ms";
236
237
238
239
240
241
242
243
244
245
246
247 public SauceOnDemandAuthentication authentication = new SauceOnDemandAuthentication(System.getProperty(SAUCE_USER_PROPERTY), System.getProperty(SAUCE_KEY_PROPERTY));
248
249 private WebDriver driver;
250
251 private String sessionId;
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266 public void setUp(String className, String testName) throws Exception {
267 if (System.getProperty(REMOTE_DRIVER_SAUCELABS_PROPERTY) == null) {
268 return;
269 }
270
271 if (System.getProperty(SAUCE_USER_PROPERTY) == null || System.getProperty(SAUCE_KEY_PROPERTY) == null) {
272 Assert.fail("-D" + SAUCE_USER_PROPERTY + " and -D" + SAUCE_KEY_PROPERTY + " must be set to saucelabs user and access key.");
273 }
274
275 DesiredCapabilities capabilities = null;
276 if ("ff".equalsIgnoreCase(System.getProperty(SAUCE_BROWSER_PROPERTY))) {
277 capabilities = DesiredCapabilities.firefox();
278 } else if ("ie".equalsIgnoreCase(System.getProperty(SAUCE_BROWSER_PROPERTY))) {
279 capabilities = DesiredCapabilities.internetExplorer();
280 capabilities.setCapability(InternetExplorerDriver.INTRODUCE_FLAKINESS_BY_IGNORING_SECURITY_DOMAINS,
281 System.getProperty(SAUCE_IE_INTRODUCE_FLAKINESS_BY_IGNORING_SECURITY_DOMAINS_PROPERTY, "true"));
282 } else if ("chrome".equalsIgnoreCase(System.getProperty(SAUCE_BROWSER_PROPERTY))) {
283 capabilities = DesiredCapabilities.chrome();
284 } else if ("opera".equalsIgnoreCase(System.getProperty(SAUCE_BROWSER_PROPERTY))) {
285 capabilities = DesiredCapabilities.opera();
286 } else if ("android".equalsIgnoreCase(System.getProperty(SAUCE_BROWSER_PROPERTY))) {
287 capabilities = DesiredCapabilities.android();
288 } else if ("safari".equalsIgnoreCase(System.getProperty(SAUCE_BROWSER_PROPERTY))) {
289 capabilities = DesiredCapabilities.safari();
290 } else if ("ipad".equalsIgnoreCase(System.getProperty(SAUCE_BROWSER_PROPERTY))) {
291 capabilities = DesiredCapabilities.ipad();
292 } else if ("iphone".equalsIgnoreCase(System.getProperty(SAUCE_BROWSER_PROPERTY))) {
293 capabilities = DesiredCapabilities.iphone();
294 } else {
295 capabilities = DesiredCapabilities.firefox();
296 }
297
298 String version = System.getProperty(SAUCE_VERSION_PROPERTY);
299 if (version == null || "0".equals(version)) {
300
301 if (!"chrome".equalsIgnoreCase(System.getProperty(SAUCE_BROWSER_PROPERTY))) {
302 throw new RuntimeException("Blank or 0 version for a browser not chrome " + System.getProperty(SAUCE_BROWSER_PROPERTY));
303 }
304
305 capabilities.setCapability("version", "");
306 } else {
307 capabilities.setCapability("version", version);
308 }
309
310 capabilities.setCapability("platform", System.getProperty(SAUCE_PLATFORM_PROPERTY, Platform.UNIX.toString()).replaceAll("_", " "));
311 capabilities.setCapability("idle-timeout", Integer.parseInt(System.getProperty(SAUCE_IDLE_TIMEOUT_SECONDS_PROPERTY, "180")));
312 capabilities.setCapability("max-duration", Integer.parseInt(System.getProperty(SAUCE_MAX_DURATION_SECONDS_PROPERTY, "600")));
313 capabilities.setCapability("name", className + "." + testName + "-" + AutomatedFunctionalTestUtils.DTS);
314 capabilities.setCapability("disable-popup-handler", System.getProperty(SAUCE_POPUP_PROPERTY, "false"));
315 capabilities.setCapability("public", System.getProperty(SAUCE_SHARE_PROPERTY, "public restricted"));
316
317 System.out.println("Requesting Saucelabs RemoteWebDriver with DesiredCapabilities of " + capabilities.toString());
318
319 this.driver = new RemoteWebDriver(
320 new URL("http://" + authentication.getUsername() + ":" + authentication.getAccessKey() + "@ondemand.saucelabs.com:80/wd/hub"),
321 capabilities);
322 this.sessionId = ((RemoteWebDriver)driver).getSessionId().toString();
323
324 System.out.println("SauceLabs job can be viewed at https://saucelabs.com/jobs/" + this.sessionId);
325 }
326
327 private void downloadResults(String className, String testName) {
328 if ("true".equals(System.getProperty(SAUCE_DOWNLOAD_SCRIPT_PROPERTY, "false"))) {
329 try {
330 String dir = determineSaveDir(className, testName);
331 String resources = "mkdir " + dir + " ; cd " + dir + " ; \n"
332 + curlSaveResourceString(className, testName, "selenium-server.log") + " ; \n"
333 + curlSaveResourceString(className, testName, "video.flv") + " ; \n"
334
335 + "cd ../\n";
336 System.out.println(resources);
337 writeFile("SauceLabsResources" + dir + ".sh", resources);
338
339
340
341 } catch (Exception e) {
342 System.out.println("Exception while writing SauceLabsResources.sh " + e.getMessage());
343 System.out.println(curlSaveResourceString(className, testName, "selenium-server.log"));
344 System.out.println(curlSaveResourceString(className, testName, "video.flv"));
345
346 }
347 }
348 }
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388 public void tearDown(boolean passed, String sessionId, String className, String testName) throws Exception {
389 if (sessionId != null && System.getProperty(REMOTE_DRIVER_SAUCELABS_PROPERTY) != null) {
390 SauceREST client = new SauceREST(System.getProperty(SauceLabsWebDriverHelper.SAUCE_USER_PROPERTY),
391 System.getProperty(SauceLabsWebDriverHelper.SAUCE_KEY_PROPERTY));
392
393
394
395 Map<String, Object> updates = new HashMap<String, Object>();
396 updates.put("passed", passed);
397 updates.put("build", System.getProperty(SAUCE_BUILD_PROPERTY, "unknown"));
398 client.updateJobInfo(sessionId, updates);
399
400 if (passed) {
401 client.jobPassed(sessionId);
402 } else {
403 client.jobFailed(sessionId);
404 }
405
406
407 Thread.sleep(Integer.parseInt(System.getProperty(SAUCE_REST_API_DELAY_MS, "5000")));
408
409 downloadResults(className, testName);
410 }
411 }
412
413 private String curlSaveResourceString(String className, String testName, String resource) {
414 return "curl -o " + deriveResourceBaseNames(className, testName, resource) + " -u " + authentication
415 .getUsername() + ":" + authentication.getAccessKey() + " " + resourceUrl(resource);
416 }
417
418 private String resourceUrl(String resource) {
419 return "http://saucelabs.com/rest/" + authentication.getUsername() + "/jobs/" + sessionId + "/results/" + resource;
420 }
421
422 private String deriveResourceBaseNames(String className, String testName, String resource) {
423 return className + "." + testName + "-"
424 + System.getProperty(SAUCE_PLATFORM_PROPERTY, Platform.UNIX.toString()) + "-"
425 + System.getProperty(SAUCE_BROWSER_PROPERTY) + "-"
426 + System.getProperty(SAUCE_VERSION_PROPERTY) + "-"
427 + System.getProperty(WebDriverUtils.REMOTE_PUBLIC_USER_PROPERTY, "admin") + "-"
428 + System.getProperty(SAUCE_BUILD_PROPERTY, "unknown_build") + "-"
429 + AutomatedFunctionalTestUtils.DTS + "-"
430 + resource;
431 }
432
433
434
435
436
437
438
439
440 public WebDriver getDriver() {
441 return driver;
442 }
443
444 @Override
445 public String getSessionId() {
446 return sessionId;
447 }
448
449
450 private String wgetnSaveResourceString(String className, String testName) {
451 String dir = determineSaveDir(className, testName);
452
453 return "wgetn https://saucelabs.com/" + sessionId + "/%04dscreenshot.png 0 50";
454 }
455
456 private String determineSaveDir(String className, String testName) {
457 String dir = deriveResourceBaseNames(className, testName, "");
458 dir = dir.substring(0, dir.length() -1);
459 return dir;
460 }
461
462 private void writeFile(String fileName, String content) throws IOException {
463 File file = new File(fileName);
464
465 if (!file.exists()) {
466 file.createNewFile();
467 }
468
469 FileWriter fw = new FileWriter(file.getAbsoluteFile());
470 BufferedWriter bw = new BufferedWriter(fw);
471 bw.write(content);
472 bw.flush();
473 bw.close();
474 }
475 }