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