001 /** 002 * Copyright 2005-2012 The Kuali Foundation 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 package edu.samplu.common; 017 018 import com.thoughtworks.selenium.Selenium; 019 import org.apache.commons.lang.RandomStringUtils; 020 import org.junit.Assert; 021 import org.openqa.selenium.By; 022 import org.openqa.selenium.NoSuchFrameException; 023 import org.openqa.selenium.WebDriver; 024 import org.openqa.selenium.chrome.ChromeDriver; 025 import org.openqa.selenium.firefox.FirefoxDriver; 026 import org.openqa.selenium.firefox.FirefoxProfile; 027 import org.openqa.selenium.remote.DesiredCapabilities; 028 import org.openqa.selenium.remote.RemoteWebDriver; 029 030 import java.io.PrintWriter; 031 import java.io.StringWriter; 032 import java.net.MalformedURLException; 033 import java.net.URL; 034 import java.net.URLEncoder; 035 import java.util.Calendar; 036 import java.util.HashMap; 037 import java.util.Iterator; 038 import java.util.Map; 039 040 import static com.thoughtworks.selenium.SeleneseTestBase.fail; 041 import static org.junit.Assert.assertEquals; 042 043 /** 044 * Common selenium test methods that should be reused rather than recreated for each test. 045 * @author Kuali Rice Team (rice.collab@kuali.org) 046 */ 047 048 public class ITUtil { 049 050 public static final String KUALI_PORTAL_TITLE = "Kuali Portal Index"; 051 public static final String DEFAULT_BASE_URL = "http://localhost:8080/kr-dev"; 052 public final static String PORTAL = "/portal.do"; 053 public final static String PORTAL_URL = ITUtil.getBaseUrlString() + ITUtil.PORTAL; 054 public final static String PORTAL_URL_ENCODED = URLEncoder.encode(PORTAL_URL); 055 public static final String DTS = Calendar.getInstance().getTimeInMillis() + ""; 056 public static final String DTS_TWO = Calendar.getInstance().getTimeInMillis() + "" + RandomStringUtils.randomAlphabetic(2).toLowerCase(); 057 public static String WAIT_TO_END_TEST = "5000"; 058 public static final String DIV_ERROR_LOCATOR = "//div[@class='error']"; 059 public static final String DIV_EXCOL_LOCATOR = "//div[@class='msg-excol']"; 060 public static final int WAIT_DEFAULT_SECONDS = 60; 061 public static final String DEFAULT_WAIT_FOR_PAGE_TO_LOAD_TIMEOUT = "30000"; 062 static Map<String, String> jiraMatches; 063 public static final String REMOTE_PUBLIC_URL_PROPERTY = "remote.public.url"; 064 public static final String REMOTE_AUTOLOGIN_PROPERTY = "remote.autologin"; 065 public static final String HUB_PROPERTY = "remote.public.hub"; 066 public static final String HUB_DRIVER_PROPERTY = "remote.public.driver"; 067 public static final String HUB_URL_PROPERTY = "http://localhost:4444/wd/hub"; 068 public static final String DONT_TEAR_DOWN_PROPERTY = "remote.driver.dontTearDown"; 069 070 static { 071 jiraMatches = new HashMap<String, String>(); 072 jiraMatches.put("Error setting property values; nested exception is org.springframework.beans.NotWritablePropertyException: Invalid property 'refreshWhenChanged' of bean class [org.kuali.rice.krad.uif.element.Action]: Bean property 'refreshWhenChanged' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?", 073 "KULRICE-8137 Agenda Rule edit Incident report Invalid property 'refreshWhenChanged'"); 074 075 jiraMatches.put("org.kuali.rice.kns.maintenance.rules.MaintenanceDocumentRuleBase.processAddCollectionLineBusinessRules(MaintenanceDocumentRuleBase.", 076 "KULRICE-8142 NPE in MaintenanceDocumentRuleBase.processAddCollectionLineBusinessRules"); 077 078 jiraMatches.put("at org.kuali.rice.krad.rules.DocumentRuleBase.isDocumentOverviewValid(DocumentRuleBase.", 079 "KULRICE-8134 NPE in DocumentRuleBase.isDocumentOverviewValid(DocumentRuleBase"); 080 081 jiraMatches.put("org.kuali.rice.krad.uif.layout.TableLayoutManager.buildLine(TableLayoutManager.", 082 "KULRICE-8160 NPE at TableLayoutManager.buildLine(TableLayoutManager"); 083 084 jiraMatches.put("Bean property 'configFileLocations' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?", 085 "KULRICE-8173 Bean property 'configFileLocations' is not writable or has an invalid setter method"); 086 087 jiraMatches.put("Bean property 'componentSecurity' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?", 088 "KULRICE-8182 JDK7 Bean property 'componentSecurity' is not readable..."); 089 090 jiraMatches.put("java.sql.SQLSyntaxErrorException: ORA-00904: \"ROUTEHEADERID\": invalid identifier", 091 "KULRICE-8277 Several ITs fail with OJB operation; bad SQL grammar []; nested exception is java.sql.SQLException: ORA-00904: \"ROUTEHEADERID\": invalid identifier"); 092 // jiraMatches.put("", 093 // ""); 094 095 } 096 097 /** 098 * "FINAL", selenium.getText("//table[@id='row']/tbody/tr[1]/td[4]" 099 * @param selenium 100 * @param docId 101 */ 102 public static void assertDocFinal(Selenium selenium, String docId) { 103 docId= "link=" + docId; 104 if(selenium.isElementPresent(docId)){ 105 assertEquals("FINAL", selenium.getText("//table[@id='row']/tbody/tr[1]/td[4]")); 106 }else{ 107 assertEquals(docId, selenium.getText("//table[@id='row']/tbody/tr[1]/td[1]")); 108 assertEquals("FINAL", selenium.getText("//table[@id='row']/tbody/tr[1]/td[4]")); 109 } 110 } 111 112 protected static String blanketApprovalCleanUpErrorText(String errorText) { 113 errorText = errorText.replace("* required field", "").replace("\n", " ").trim(); // bit of extra ui text we don't care about 114 return errorText; 115 } 116 117 /** 118 * Generic blanket approve behavior 119 * @param selenium 120 * @throws InterruptedException 121 */ 122 public static void blanketApprove(Selenium selenium) throws InterruptedException { 123 ITUtil.checkForIncidentReport(selenium, "methodToCall.blanketApprove"); 124 ITUtil.waitAndClick(selenium, "methodToCall.blanketApprove"); 125 selenium.waitForPageToLoad(DEFAULT_WAIT_FOR_PAGE_TO_LOAD_TIMEOUT); 126 Thread.sleep(2000); 127 128 if (selenium.isElementPresent(DIV_ERROR_LOCATOR)) { 129 String errorText = selenium.getText(DIV_ERROR_LOCATOR); 130 if (errorText != null && errorText.contains("error(s) found on page.")) { 131 errorText = blanketApprovalCleanUpErrorText(errorText); 132 if (selenium.isElementPresent(DIV_EXCOL_LOCATOR)) { // not present if errors are at the bottom of the page (see left-errmsg below) 133 errorText = blanketApprovalCleanUpErrorText(selenium.getText(DIV_EXCOL_LOCATOR));// + "\n" + selenium.getHtmlSource()); // replacing errorText as DIV_EXCOL_LOCATOR includes the error count 134 } 135 if (selenium.isElementPresent("//div[@class='left-errmsg-tab']/div/div")) { 136 errorText = errorText + blanketApprovalCleanUpErrorText(selenium.getText("//div[@class='left-errmsg-tab']/div/div")); 137 } 138 139 // if (selenium.isElementPresent("//div[@class='left-errmsg']/div")) { 140 // errorText = errorText + " " + selenium.getText("//div[@class='left-errmsg']/div/div[1]"); 141 // } 142 Assert.fail(errorText); 143 } 144 } 145 ITUtil.checkForIncidentReport(selenium, "//img[@alt='doc search']"); 146 waitAndClick(selenium, "//img[@alt='doc search']"); 147 selenium.waitForPageToLoad(DEFAULT_WAIT_FOR_PAGE_TO_LOAD_TIMEOUT); 148 assertEquals("Kuali Portal Index", selenium.getTitle()); 149 try { 150 selenium.selectFrame("iframeportlet"); 151 } catch (NoSuchFrameException nsfe) { 152 // do nothing don't fail on missing frames 153 } 154 selenium.click("//input[@name='methodToCall.search' and @value='search']"); 155 selenium.waitForPageToLoad(DEFAULT_WAIT_FOR_PAGE_TO_LOAD_TIMEOUT); 156 } 157 158 /** 159 * "//li[@class='uif-errorMessageItem']" 160 * @param selenium 161 * @param message 162 */ 163 public static void checkErrorMessageItem(Selenium selenium, String message) { 164 final String error_locator = "//li[@class='uif-errorMessageItem']"; 165 if (selenium.isElementPresent(error_locator)) { 166 String errorText = selenium.getText(error_locator); 167 if (errorText != null && errorText.contains("errors")) { 168 Assert.fail(errorText + message); 169 } 170 } 171 } 172 173 174 /** 175 * In order to run as a smoke test the ability to set the baseUrl via the JVM arg remote.public.url is required. 176 * Trailing slashes are trimmed. If the remote.public.url does not start with http:// it will be added. 177 * @return http://localhost:8080/kr-dev by default else the value of remote.public.url 178 */ 179 public static String getBaseUrlString() { 180 String baseUrl = System.getProperty(REMOTE_PUBLIC_URL_PROPERTY); 181 if (baseUrl == null) { 182 baseUrl = DEFAULT_BASE_URL; 183 } 184 baseUrl = prettyHttp(baseUrl); 185 return baseUrl; 186 } 187 188 /** 189 * Append http:// if not present. Remove trailing / 190 * @param baseUrl 191 * @return 192 */ 193 public static String prettyHttp(String baseUrl) { 194 if (baseUrl.endsWith("/")) { 195 baseUrl = baseUrl.substring(0, baseUrl.length() - 1); 196 } 197 if (!baseUrl.startsWith("http")) { 198 baseUrl = "http://" + baseUrl; 199 } 200 return baseUrl; 201 } 202 203 /** 204 * In order to run as a smoke test under selenium grid the ability to set the hubUrl via the JVM arg remote.public.hub is required. 205 * Trailing slashes are trimmed. If the remote.public.hub does not start with http:// it will be added. 206 * @return http://localhost:4444/wd/hub by default else the value of remote.public.hub 207 */ 208 public static String getHubUrlString() { 209 String hubUrl = System.getProperty(HUB_PROPERTY); 210 if (hubUrl == null) { 211 hubUrl = HUB_URL_PROPERTY; 212 } 213 hubUrl = prettyHttp(hubUrl); 214 if (!hubUrl.endsWith("/wd/hub")) { 215 hubUrl = hubUrl + "/wd/hub"; 216 } 217 return hubUrl; 218 } 219 220 /** 221 * remote.public.driver set to chrome or firefox (null assumes firefox) 222 * if remote.public.hub is set a RemoteWebDriver is created (Selenium Grid) 223 * @return WebDriver or null if unable to create 224 */ 225 public static WebDriver getWebDriver() { 226 String driverParam = System.getProperty(HUB_DRIVER_PROPERTY); 227 String hubParam = System.getProperty(HUB_PROPERTY); 228 if (hubParam == null) { 229 if (driverParam == null || "firefox".equalsIgnoreCase(driverParam)) { 230 FirefoxProfile profile = new FirefoxProfile(); 231 profile.setEnableNativeEvents(false); 232 return new FirefoxDriver(profile); 233 } else if ("chrome".equalsIgnoreCase(driverParam)) { 234 return new ChromeDriver(); 235 } 236 } else { 237 try { 238 if (driverParam == null || "firefox".equalsIgnoreCase(driverParam)) { 239 return new RemoteWebDriver(new URL(ITUtil.getHubUrlString()), DesiredCapabilities.firefox()); 240 } else if ("chrome".equalsIgnoreCase(driverParam)) { 241 return new RemoteWebDriver(new URL(ITUtil.getHubUrlString()), DesiredCapabilities.chrome()); 242 } 243 } catch (MalformedURLException mue) { 244 System.out.println(ITUtil.getHubUrlString() + " " + mue.getMessage()); 245 mue.printStackTrace(); 246 } 247 } 248 return null; 249 } 250 251 /** 252 * If the JVM arg remote.autologin is set, auto login as admin will not be done. 253 * @param selenium to login with 254 */ 255 public static void loginSe(Selenium selenium) { 256 loginSe(selenium, "admin"); 257 } 258 259 /** 260 * If the JVM arg remote.autologin is set, auto login as admin will not be done. 261 * @param driver 262 * @param userName 263 * @throws InterruptedException 264 */ 265 public static void login(WebDriver driver, String userName) throws InterruptedException { 266 if (System.getProperty(REMOTE_AUTOLOGIN_PROPERTY) == null) { 267 driver.findElement(By.name("__login_user")).clear(); 268 driver.findElement(By.name("__login_user")).sendKeys(userName); 269 driver.findElement(By.cssSelector("input[type=\"submit\"]")).click(); 270 Thread.sleep(1000); 271 String contents = driver.getPageSource(); 272 checkForInvalidUserName(userName, contents); 273 } 274 } 275 276 private static void checkForInvalidUserName(String userName, String contents) { 277 if (contents.indexOf("Invalid username") > -1) { 278 Assert.fail("Invalid username " + userName); 279 } 280 } 281 282 /** 283 * If the JVM arg remote.autologin is set, auto login as admin will not be done. 284 * @param selenium to login with 285 */ 286 public static void loginSe(Selenium selenium, String user) { 287 if (System.getProperty(REMOTE_AUTOLOGIN_PROPERTY) == null) { 288 try { 289 selenium.waitForPageToLoad(DEFAULT_WAIT_FOR_PAGE_TO_LOAD_TIMEOUT); 290 } catch (Exception e) { 291 Assert.fail("Login page not loaded app started?"); 292 } 293 if (!"Login".equals(selenium.getTitle())) { 294 fail("Title is not Login as expected, but " + selenium.getTitle()); 295 } 296 selenium.type("__login_user", user); 297 selenium.click("//input[@type='submit']"); //using css selector fails 298 selenium.waitForPageToLoad(DEFAULT_WAIT_FOR_PAGE_TO_LOAD_TIMEOUT); 299 String contents = selenium.getHtmlSource(); 300 checkForInvalidUserName(user, contents); 301 } 302 } 303 304 /** 305 * Write the given stack trace into a String 306 * @param throwable whose stack trace to return 307 * @return String of the given throwable's stack trace. 308 */ 309 public static String stackTrace(Throwable throwable) { 310 StringWriter wrt=new StringWriter(); 311 PrintWriter pw=new PrintWriter(wrt); 312 throwable.printStackTrace(pw); 313 pw.flush(); 314 return wrt.toString(); 315 } 316 317 /** 318 * Setting the JVM arg remote.driver.dontTearDown to y or t leaves the browser window open when the test has completed. Valuable when debugging, updating, or creating new tests. 319 * When implementing your own tearDown method rather than an inherited one, it is a common courtesy to include this check and not stop and shutdown the browser window to make it easy debug or update your test. 320 * {@code } 321 * @return true if the dontTearDownProperty is not set. 322 */ 323 public static boolean dontTearDownPropertyNotSet() { 324 return System.getProperty(DONT_TEAR_DOWN_PROPERTY) == null || 325 "f".startsWith(System.getProperty(DONT_TEAR_DOWN_PROPERTY).toLowerCase()) || 326 "n".startsWith(System.getProperty(DONT_TEAR_DOWN_PROPERTY).toLowerCase()); 327 } 328 329 /** 330 * Wait 60 seconds for the elementLocator to be present or fail. Click if present 331 * @param selenium 332 * @param elementLocator 333 * @throws InterruptedException 334 */ 335 public static void waitAndClick(Selenium selenium, String elementLocator) throws InterruptedException { 336 waitAndClick(selenium, elementLocator, WAIT_DEFAULT_SECONDS); 337 } 338 339 /** 340 * Wait 60 seconds for the elementLocator to be present or fail. Click if present 341 * @param selenium 342 * @param elementLocator 343 * @param message 344 * @throws InterruptedException 345 */ 346 public static void waitAndClick(Selenium selenium, String elementLocator, String message) throws InterruptedException { 347 waitAndClick(selenium, elementLocator, WAIT_DEFAULT_SECONDS, message); 348 } 349 350 /** 351 * Wait the given seconds for the elementLocator to be present or fail 352 * @param selenium 353 * @param elementLocator 354 * @param seconds 355 * @throws InterruptedException 356 */ 357 public static void waitAndClick(Selenium selenium, String elementLocator, int seconds) throws InterruptedException { 358 waitAndClick(selenium, elementLocator, seconds, ""); 359 } 360 361 /** 362 * Wait the given seconds for the elementLocator to be present or fail 363 * @param selenium 364 * @param elementLocator 365 * @param seconds 366 * @param message 367 * @throws InterruptedException 368 */ 369 public static void waitAndClick(Selenium selenium, String elementLocator, int seconds, String message) throws InterruptedException { 370 waitForElement(selenium, elementLocator, seconds, message); 371 selenium.click(elementLocator); 372 Thread.sleep(1000); 373 ITUtil.checkForIncidentReport(selenium, elementLocator, message); 374 } 375 376 /** 377 * Wait the 60 seconds for the elementLocator to be present or fail, when present type the text. 378 * @param selenium 379 * @param elementLocator 380 * @param text 381 * @throws InterruptedException 382 */ 383 public static void waitAndType(Selenium selenium, String elementLocator, String text) throws InterruptedException { 384 waitAndType(selenium, elementLocator, text, ""); 385 } 386 387 /** 388 * Wait the 60 seconds for the elementLocator to be present or fail, when present type the text. Include failure message on fail. 389 * @param selenium 390 * @param elementLocator 391 * @param text 392 * @param message 393 * @throws InterruptedException 394 */ 395 public static void waitAndType(Selenium selenium, String elementLocator, String text, String message) throws InterruptedException { 396 waitAndType(selenium, elementLocator, WAIT_DEFAULT_SECONDS, text, message); 397 } 398 399 /** 400 * Wait the given seconds for the elementLocator to be present or fail, when present type the text. 401 * @param selenium 402 * @param elementLocator 403 * @param seconds 404 * @param text 405 * @param message 406 * @throws InterruptedException 407 */ 408 public static void waitAndType(Selenium selenium, String elementLocator, int seconds, String text, String message) throws InterruptedException { 409 waitForElement(selenium, elementLocator, seconds, message); 410 selenium.type(elementLocator, text); 411 Thread.sleep(1000); 412 } 413 414 /** 415 * Wait 60 seconds for the elementLocator to be present or fail 416 * @param selenium 417 * @param elementLocator 418 * @throws InterruptedException 419 */ 420 public static void waitForElement(Selenium selenium, String elementLocator) throws InterruptedException { 421 waitForElement(selenium, elementLocator, WAIT_DEFAULT_SECONDS); 422 } 423 424 /** 425 * Wait 60 seconds for the elementLocator to be present or fail 426 * @param selenium 427 * @param elementLocator 428 * @param message 429 * @throws InterruptedException 430 */ 431 public static void waitForElement(Selenium selenium, String elementLocator, String message) throws InterruptedException { 432 waitForElement(selenium, elementLocator, WAIT_DEFAULT_SECONDS, message); 433 } 434 435 /** 436 * Wait the given seconds for the elementLocator to be present or fail 437 * @param selenium 438 * @param elementLocator 439 * @param seconds 440 * @throws InterruptedException 441 */ 442 public static void waitForElement(Selenium selenium, String elementLocator, int seconds) throws InterruptedException { 443 waitForElement(selenium, elementLocator, WAIT_DEFAULT_SECONDS, ""); 444 } 445 446 /** 447 * Wait the given seconds for the elementLocator to be present or fail 448 * @param selenium 449 * @param elementLocator 450 * @param seconds 451 * @param message 452 * @throws InterruptedException 453 */ 454 public static void waitForElement(Selenium selenium, String elementLocator, int seconds, String message) throws InterruptedException { 455 boolean failed = false; 456 for (int second = 0;; second++) { 457 if (second >= seconds) failed = true; 458 try { if (failed || selenium.isElementPresent(elementLocator)) break; } catch (Exception e) {} 459 Thread.sleep(1000); 460 } 461 ITUtil.checkForIncidentReport(selenium, elementLocator); // after timeout to be sure page is loaded 462 if (failed) fail("timeout of " + seconds + " seconds waiting for " + elementLocator + " " + message); 463 } 464 465 /** 466 * Wait the given seconds for the elementLocator to be present or fail 467 * @param selenium 468 * @param elementLocator 469 * @throws InterruptedException 470 */ 471 public static void waitForElementVisible(Selenium selenium, String elementLocator) throws InterruptedException { 472 waitForElementVisible(selenium, elementLocator, WAIT_DEFAULT_SECONDS, ""); 473 } 474 475 /** 476 * Wait 60 seconds for the elementLocator to be present or fail including the given message 477 * @param selenium 478 * @param elementLocator 479 * @param message 480 * @throws InterruptedException 481 */ 482 public static void waitForElementVisible(Selenium selenium, String elementLocator, String message) throws InterruptedException { 483 waitForElementVisible(selenium, elementLocator, WAIT_DEFAULT_SECONDS, message); 484 } 485 486 /** 487 * Wait the given seconds for the elementLocator to be present or fail 488 * @param selenium 489 * @param elementLocator 490 * @param seconds 491 * @throws InterruptedException 492 */ 493 public static void waitForElementVisible(Selenium selenium, String elementLocator, int seconds, String message) throws InterruptedException { 494 for (int second = 0;; second++) { 495 if (second >= seconds) fail("timeout of " + seconds + " seconds waiting for " + elementLocator + " " + message); 496 try { if (selenium.isVisible(elementLocator)) break; } catch (Exception e) {} 497 Thread.sleep(1000); 498 } 499 } 500 501 /** 502 * Wait for 60 seconds for the selenium.getTitle to match the given title then fail. 503 * @param selenium 504 * @param title 505 * @throws InterruptedException 506 */ 507 public static void waitForTitleToEqual(Selenium selenium, String title) throws InterruptedException { 508 waitForTitleToEqual(selenium, title, ""); 509 } 510 511 /** 512 * Wait for 60 seconds for the selenium.getTitle to match the given title then fail including the given message. 513 * @param selenium 514 * @param title 515 * @param message 516 * @throws InterruptedException 517 */ 518 public static void waitForTitleToEqual(Selenium selenium, String title, String message) throws InterruptedException { 519 Thread.sleep(2000); 520 // for (int second = 0;; second++) { 521 // if (second >= WAIT_DEFAULT_SECONDS) fail(("timeout of " + WAIT_DEFAULT_SECONDS + " seconds waiting for title to equal " + title + " " + message).trim()); 522 // try { if (title.equals(selenium.getTitle())) break; } catch (Exception e) {} 523 // Thread.sleep(1000); 524 // } 525 } 526 527 /** 528 * Check the selenium contents for an Incident Report failure with Incident Report Details 529 * @param selenium 530 * @param linkLocator 531 */ 532 public static void checkForIncidentReport(Selenium selenium, String linkLocator) { 533 checkForIncidentReport(selenium, linkLocator, ""); 534 } 535 536 /** 537 * Fails if a Incident Report is detected, extracting and reporting the View Id, Document Id, and StackTrace 538 * @param selenium 539 * @param linkLocator used only in the failure message 540 */ 541 public static void checkForIncidentReport(Selenium selenium, String linkLocator, String message) { 542 selenium.waitForPageToLoad(DEFAULT_WAIT_FOR_PAGE_TO_LOAD_TIMEOUT); 543 String contents = selenium.getHtmlSource(); 544 checkForIncidentReport(contents, linkLocator, message); 545 } 546 547 protected static void checkForIncidentReport(String contents, String linkLocator, String message) { 548 if (contents != null && 549 contents.contains("Incident Report") && 550 !contents.contains("portal.do?channelTitle=Incident%20Report") && // Incident Report link on sampleapp KRAD tab 551 !contents.contains("portal.do?channelTitle=Incident Report") && // Incident Report link on sampleapp KRAD tab IE8 552 !contents.contains("uitest?viewId=Travel-testView2") && 553 !contents.contains("SeleniumException")) { // selenium timeouts have Incident Report in them 554 try { 555 if (contents.indexOf("Incident Feedback") > -1) { 556 Iterator<String> iter = jiraMatches.keySet().iterator(); 557 String key = null; 558 while (iter.hasNext()) { 559 key = iter.next(); 560 if (contents.contains(key)) { 561 Assert.fail("https://jira.kuali.org/browse/" + jiraMatches.get(key)); 562 } 563 } 564 565 String chunk = contents.substring(contents.indexOf("Incident Feedback"), contents.lastIndexOf("</div>") ); 566 String docId = chunk.substring(chunk.lastIndexOf("Document Id"), chunk.indexOf("View Id")); 567 docId = docId.substring(0, docId.indexOf("</span>")); 568 docId = docId.substring(docId.lastIndexOf(">") + 2, docId.length()); 569 570 String viewId = chunk.substring(chunk.lastIndexOf("View Id"), chunk.indexOf("Error Message")); 571 viewId = viewId.substring(0, viewId.indexOf("</span>")); 572 viewId = viewId.substring(viewId.lastIndexOf(">") + 2, viewId.length()); 573 574 String stackTrace = chunk.substring(chunk.lastIndexOf("(only in dev mode)"), chunk.length()); 575 stackTrace = stackTrace.substring(stackTrace.indexOf("<span id=\"") + 3, stackTrace.length()); 576 stackTrace = stackTrace.substring(stackTrace.indexOf("\">") + 2, stackTrace.indexOf("</span>")); 577 578 // System.out.println(docId); 579 // System.out.println(viewId); 580 // System.out.println(stackTrace); 581 Assert.fail("\nIncident report " + message + " navigating to " 582 + linkLocator 583 + " : View Id: " 584 + viewId.trim() 585 + " Doc Id: " 586 + docId.trim() 587 + "\nStackTrace: " 588 + stackTrace.trim()); 589 } else { 590 Assert.fail("\nIncident report detected " + message + "\nContents that triggered exception: " + deLinespace(contents)); 591 } 592 } catch (IndexOutOfBoundsException e) { 593 Assert.fail("\nIncident report detected " + message + " but there was an exception during processing: " + e.getMessage() + "\nStack Trace from processing exception" + stackTrace(e) + "\nContents that triggered exception: " + deLinespace( 594 contents)); 595 } 596 } else { 597 if (contents.contains("HTTP Status 404")) { 598 Assert.fail("\nHTTP Status 404 " + linkLocator + " " + message + " " + "\ncontents:" + contents); 599 } 600 } 601 } 602 603 protected static String deLinespace(String contents) { 604 while (contents.contains("\n\n")) { 605 contents = contents.replaceAll("\n\n", "\n"); 606 } 607 return contents; 608 } 609 }