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