001/** 002 * Copyright 2005-2015 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 */ 016package org.kuali.rice.testtools.selenium; 017 018import org.junit.Assert; 019import org.kuali.rice.testtools.common.JiraAwareFailable; 020import org.kuali.rice.testtools.common.JiraAwareFailureUtils; 021import org.openqa.selenium.By; 022import org.openqa.selenium.WebDriver; 023import org.openqa.selenium.WebElement; 024 025import java.util.Arrays; 026import java.util.List; 027 028/** 029 * <p> 030 * Jira Aware Automated Functional Test Base. 031 * </p><p> 032 * <img src="https://wiki.kuali.org/download/attachments/330268881/JiraAwareFailure.png"/> 033 * <ul> 034 * <li>{@see JiraAwareWebDriverUtils}</li> 035 * <li>{@see JiraAwareFailable}</li> 036 * <li>{@see JiraAwareFailure}</li> 037 * </ul> 038 * TODO: promote the various jiraAware methods from WebDriverLegacyITBase 039 * </p> 040 * 041 * @author Kuali Rice Team (rice.collab@kuali.org) 042 */ 043public abstract class JiraAwareAftBase extends AutomatedFunctionalTestBase implements JiraAwareFailable { 044 045 /** 046 * Test state, used for Saucelabs REST API call to set test state via @{see SauceLabsWebDriverHelper#tearDown}. 047 */ 048 private boolean passed = false; 049 050 /** 051 * Implement to check for Incident Report or other on screen errors, should call {@see JiraAwareFailable#fail} to fail, 052 * without calling any of the jiraAwareFail methods to avoid an infinite loop. 053 * 054 * @param locator used in failure message if there is an incident report can be blank 055 * @param message used in failure message if there is an incident report can be blank 056 */ 057 protected abstract void checkForIncidentReport(String locator, String message); 058 059 /** 060 * WebDriver used in fail and pass to display jGrowl messages. 061 * 062 * @return WebDriver used to display jGrowl messages on fail and pass 063 */ 064 protected abstract WebDriver getDriver(); 065 066 /** 067 * {@see WebDriverUtils#assertButtonDisabledByText} 068 * 069 * @param buttonText of button to assert is disabled 070 */ 071 protected void assertButtonDisabledByText(String buttonText) { 072 JiraAwareWebDriverUtils.assertButtonDisabledByText(getDriver(), buttonText, this); 073 } 074 075 /** 076 * {@see WebDriverUtils.assertButtonEnabledByText}. 077 * 078 * @param buttonText of button to assert is disabled 079 */ 080 protected void assertButtonEnabledByText(String buttonText) { 081 JiraAwareWebDriverUtils.assertButtonEnabledByText(getDriver(), buttonText, this); 082 } 083 084 protected void assertDataTableContains(String[][] data) throws InterruptedException { 085 boolean dataPresent = true; 086 String missingMessage = ""; 087 String dataTableRow; 088 for (int i = 0, s = data.length; i < s; i++) { 089 dataTableRow = findDataTableRow(data[i][0]).getText(); 090 for (int j = 1, t = data[i].length; j < t; j++) { 091 if (!dataTableRow.contains(data[i][j])) { 092 dataPresent = false; 093 missingMessage += data[i][j] + " not present in data table row containing " + data[i][0] + ". "; 094 } 095 } 096 WebDriverUtils.jGrowl(getDriver(), "Assert DataTable Row", false, "Assert datatable row '" + dataTableRow 097 + "' contains '" + Arrays.toString(data[i]) + "' " + dataPresent); 098 } 099 if (!dataPresent) { 100 jiraAwareFail(missingMessage); 101 } 102 } 103 104 protected void assertDataTableContains(String[][] data, String tableClass) throws InterruptedException { 105 boolean dataPresent = true; 106 String missingMessage = ""; 107 String dataTableRow; 108 for (int i = 0, s = data.length; i < s; i++) { 109 dataTableRow = findDataTableRow(data[i][0], tableClass).getText(); 110 for (int j = 1, t = data[i].length; j < t; j++) { 111 if (!dataTableRow.contains(data[i][j])) { 112 dataPresent = false; 113 missingMessage += data[i][j] + " not present in data table row containing " + data[i][0] + ". "; 114 } 115 } 116 } 117 if (!dataPresent) { 118 jiraAwareFail(missingMessage); 119 } 120 } 121 122 protected void assertElementPresentByName(String name) { 123 assertElementPresentByName(name, this.getClass().toString()); 124 } 125 126 protected void assertElementPresentByName(String name, String message) { 127 try { 128 findElement(By.name(name)); 129 } catch (Throwable t) { 130 jiraAwareFail(name + " not present " + message); 131 } 132 } 133 134 protected void assertElementPresentByXpath(String locator) { 135 assertElementPresentByXpath(locator, this.getClass().toString()); 136 } 137 138 protected void assertElementPresent(By by) { 139 assertElementPresent(by, this.getClass().toString()); 140 } 141 142 protected void assertElementPresent(By by, String message) { 143 try { 144 findElement(by); 145 } catch (Throwable t) { 146 jiraAwareFail(by, message, t); 147 } 148 } 149 150 protected void assertElementPresentByXpath(String locator, String message) { 151 try { 152 findElement(By.xpath(locator)); 153 } catch (Throwable t) { 154 jiraAwareFail(By.xpath(locator), message, t); 155 } 156 } 157 158 protected void assertElementPresentByLinkText(String linkText) { 159 try { 160 findElement(By.linkText(linkText)); 161 } catch (Throwable t) { 162 jiraAwareFail(By.cssSelector(linkText), this.getClass().toString(), t); 163 } 164 165 } 166 167 protected void assertElementPresent(String locator) { 168 try { 169 findElement(By.cssSelector(locator)); 170 } catch (Throwable t) { 171 jiraAwareFail(By.cssSelector(locator), this.getClass().toString(), t); 172 } 173 } 174 175 protected void assertEquals(boolean expected, boolean actual) { 176 if (expected != actual) { 177 jiraAwareFail("Expected \"" + expected + "\" but saw \"" + actual + "\" instead"); 178 } 179 } 180 181 protected void assertEquals(int expected, int actual) { 182 if (expected != actual) { 183 jiraAwareFail("Expected \"" + expected + "\" but saw \"" + actual + "\" instead"); 184 } 185 } 186 187 protected void assertEquals(String message, int expected, int actual) { 188 if (expected != actual) { 189 jiraAwareFail("Expected \"" + expected + "\" but saw \"" + actual + "\" instead " + message); 190 } 191 } 192 193 194 protected void assertEquals(String expected, String actual) { 195 if (!expected.equals(actual)) { 196 jiraAwareFail("Expected \"" + expected + "\" but saw \"" + actual + "\" instead in " + getClass().toString()); 197 } 198 } 199 200 protected void assertEquals(String message, String expected, String actual) { 201 if (!expected.equals(actual)) { 202 jiraAwareFail("Expected \"" + expected + "\" but saw \"" + actual + "\" instead " + message); 203 } 204 } 205 206 /** 207 * If booleanToAssertFalse is true call {@see jiraAwareFail}. 208 * 209 * @param booleanToAssertFalse 210 */ 211 protected void assertFalse(boolean booleanToAssertFalse) { 212 JiraAwareWebDriverUtils.assertFalse(booleanToAssertFalse, this); 213 } 214 215 /** 216 * If booleanToAssertFalse is true call {@see jiraAwareFail}. 217 * 218 * @param message to include if booleanToAssertTrue is true 219 * @param booleanToAssertFalse 220 */ 221 protected void assertFalse(String message, boolean booleanToAssertFalse) { 222 JiraAwareWebDriverUtils.assertFalse(message, booleanToAssertFalse, this); 223 } 224 225 protected void assertIsVisible(String locator) { 226 if (!isVisible(locator)) { 227 jiraAwareFail(locator + " is not visible and should be"); 228 } 229 } 230 231 protected void assertIsVisible(By by, String message) { 232 if (!isVisible(by)) { 233 jiraAwareFail(by + " not visible " + message); 234 } 235 } 236 237 protected void assertIsVisibleById(String id) { 238 if (!isVisibleById(id)) { 239 jiraAwareFail(id + " is not visible and should be"); 240 } 241 } 242 243 protected void assertIsVisibleByXpath(String xpath, String message) { 244 if (!isVisibleByXpath(xpath)) { 245 jiraAwareFail(xpath + " not visible " + message); 246 } 247 } 248 249 protected void assertIsNotVisible(By by) { 250 assertIsNotVisible(by, this.getClass().toString()); 251 } 252 253 protected void assertIsNotVisible(By by, String message) { 254 if (isVisible(by)) { 255 jiraAwareFail(by + " is visible and should not be " + message); 256 } 257 } 258 259 protected void assertIsNotVisible(String locator) { 260 if (isVisible(locator)) { 261 jiraAwareFail(locator + " is visible and should not be"); 262 } 263 } 264 265 protected void assertIsNotVisibleByXpath(String xpath) { 266 if (isVisible(By.xpath(xpath))) { 267 jiraAwareFail(xpath + " is visible and should not be"); 268 } 269 } 270 271 protected void assertIsNotVisibleByXpath(String xpath, String message) { 272 if (isVisibleByXpath(xpath)) { 273 jiraAwareFail(xpath + " visible and should not be " + message); 274 } 275 } 276 277 protected void assertLabeledTextNotPresent(String[][] labeledText) { 278 boolean allLabeledTextNotPresent = true; 279 String missingMessage = ""; 280 for (int i = 0, s = labeledText.length; i < s; i++) { 281 if (isLabeledTextPresent(labeledText[i][0], labeledText[i][1])) { 282 allLabeledTextNotPresent = false; 283 missingMessage += "Text: " + labeledText[i][1] + " labeled by: " + labeledText[i][0] + " present. "; 284 } 285 } 286 if (!allLabeledTextNotPresent) { 287 jiraAwareFail(missingMessage); 288 } 289 } 290 291 protected void assertLabeledTextPresent(String[][] labeledText) { 292 boolean allLabeledTextPresent = true; 293 String missingMessage = ""; 294 for (int i = 0, s = labeledText.length; i < s; i++) { 295 if (!isLabeledTextPresent(labeledText[i][0], labeledText[i][1])) { 296 allLabeledTextPresent = false; 297 missingMessage += "Text: " + labeledText[i][1] + " labeled by: " + labeledText[i][0] + " not present. "; 298 } 299 } 300 if (!allLabeledTextPresent) { 301 jiraAwareFail(missingMessage); 302 } 303 } 304 305 /** 306 * Looks for values in input or select 307 * @param labeledText 308 */ 309 protected void assertLabeledInputTextPresent(String[][] labeledText) { 310 boolean allLabeledTextPresent = true; 311 String missingMessage = ""; 312 for (int i = 0, s = labeledText.length; i < s; i++) { 313 if (!isLabeledInputTextPresent(labeledText[i][0], labeledText[i][1])) { 314 allLabeledTextPresent = false; 315 missingMessage += "Text: " + labeledText[i][1] + " labeled by: " + labeledText[i][0] + " not present. "; 316 } 317 } 318 if (!allLabeledTextPresent) { 319 jiraAwareFail(missingMessage); 320 } 321 } 322 323 protected void assertLabeledTextPresent(String label, String text) { 324 if (!isLabeledTextPresent(label, text)) { 325 jiraAwareFail("Text: " + text + " labeled by: " + label + " not present"); 326 } 327 } 328 329 protected void assertResultCount(String count) throws InterruptedException { 330 jiraAwareWaitFor(By.cssSelector("div.dataTables_info"), "result count for " + this.getClass().toString()); 331 assertTextPresent("of " + count + " entries", "div.dataTables_info", this.getClass().toString()); 332 } 333 334 /** 335 * <b>WARNING:</b> this only does a check against the page source. The form url can have random character that match 336 * simple text. A narrowly scoped locator for {@see #assertTextPresent(String String String)} 337 * 338 * @param text 339 */ 340 protected void assertTextPresent(String text) { 341 assertTextPresent(text, this.getClass().toString()); 342 } 343 344 /** 345 * <b>WARNING:</b> this only does a check against the page source. The form url can have random character that match simple text 346 * @param text 347 */ 348 protected void assertTextPresent(String text, String message) { 349 WebDriverUtils.jGrowl(getDriver(), "Assert Text Present", false, "Assert text '" + text + "' is present."); 350 String pageSource = getDriver().getPageSource(); 351 if (!pageSource.contains(text)) { 352 jiraAwareFail(text + " not present " + message); 353 } 354 WebDriverUtils.highlightElement(getDriver(), By.xpath("//*[contains(text(), '" + text + "')]")); 355 } 356 357 /** 358 * @param text 359 */ 360 protected void assertTextPresent(String text, String cssSelector, String message){ 361 WebElement element = findElement(By.cssSelector(cssSelector)); 362 if (!element.getText().contains(text)){ 363 jiraAwareFail(text + " for " + cssSelector + " not present " + message); 364 } 365 } 366 367 /** 368 * Asset that the given text does not occur in the page 369 * Warning, this only does a check against the page source. The form url can have random character that match simple text 370 * @param text the text to search for 371 */ 372 protected void assertTextNotPresent(String text) { 373 assertTextNotPresent(text, this.getClass().toString()); 374 } 375 376 /** 377 * Assert that the given text does not occur in the page, and add an additional message to the failure 378 * @param text the text to search for 379 * @param message the message to add to the failure 380 */ 381 protected void assertTextNotPresent(String text, String message) { 382 String contents = getDriver().getPageSource(); 383 if (contents.contains(text)) { 384 jiraAwareFail(text + " is present and should not be " + message); 385 } 386 } 387 388 /** 389 * @param text 390 */ 391 protected void assertTextNotPresent(String text, String cssSelector, String message){ 392 WebElement element = findElement(By.cssSelector(cssSelector)); 393 if (element.getText().contains(text)){ 394 jiraAwareFail(text + " for " + cssSelector + " is present and shouldn't be " + message); 395 } 396 } 397 398 /** 399 * If booleanToAssertTrue is false call {@see jiraAwareFail}. 400 * 401 * @param booleanToAssertTrue 402 */ 403 protected void assertTrue(boolean booleanToAssertTrue) { 404 JiraAwareWebDriverUtils.assertTrue(getClass().toString(), booleanToAssertTrue, this); 405 } 406 407 /** 408 * If booleanToAssertTrue is false call {@see jiraAwareFail}. 409 * 410 * @param message to include if booleanToAssertTrue is false 411 * @param booleanToAssertTrue 412 */ 413 protected void assertTrue(String message, boolean booleanToAssertTrue) { 414 JiraAwareWebDriverUtils.assertTrue(message, booleanToAssertTrue, this); 415 } 416 417 /** 418 * {@inheritDoc} 419 * <p> 420 * Set passed to false, call jGrowl sticky with the given message, then fails using {@see JiraAwareFailable#fail}. 421 * </p> 422 * @param message to display with failure 423 */ 424 @Override 425 public void fail(String message) { 426 passed = false; 427 WebDriverUtils.jGrowl(getDriver(), "Failure " + getClass().getSimpleName(), true, message); 428 Assert.fail(message); // The final fail that JiraAwareFailure calls, do not change this to a JiraAwareFailure. 429 } 430 431 protected WebElement findDataTableRow(String keyText) throws InterruptedException { 432 return findDataTableRow(keyText, "dataTable"); 433 } 434 435 protected WebElement findDataTableRow(String keyText, String className) throws InterruptedException { 436 jiraAwareWaitFor(By.className(className)); 437 WebElement element = findElement(By.className(className)); 438 return findElement(By.xpath("./*/tr//*[contains(text(), '" + keyText + "')]/ancestor::tr"), element); 439 } 440 441 /** 442 * {@see WebDriverUtils#findElement}. 443 * 444 * @param by to find element with 445 * @return WebElement found with given by 446 */ 447 protected WebElement findElement(By by) { 448 try { 449 return WebDriverUtils.findElement(getDriver(), by); 450 } catch (Throwable t) { 451 checkForIncidentReport(by.toString(), t.getMessage()); 452 jiraAwareFail(by.toString(), t.getMessage(), t); 453 } 454 return null; // required by compiler, never reached 455 } 456 457 protected WebElement findElement(By by, WebElement elementToFindOn) { 458 try { 459 WebElement found = elementToFindOn.findElement(by); 460 WebDriverUtils.highlightElement(getDriver(), found); 461 return found; 462 } catch (Throwable t) { 463 checkForIncidentReport(by.toString(), t.getMessage()); 464 jiraAwareFail(by.toString(), t.getMessage() + " " + this.getClass().toString(), t); 465 } 466 return null; // required by compiler, never reached 467 } 468 469 protected boolean isLabeledTextPresent(String label, String text) { 470 WebElement element = findElement(By.xpath("//tr/th/label[contains(text(), '" + label + "')]/ancestor::tr/td")); 471 String labeledText = element.getText().trim(); 472 WebDriverUtils.jGrowl(getDriver(), "Is Labeled Text Present", false, "Is text '" + text + "' present for label '" 473 + label + "'? " + labeledText.contains(text) + " saw " + labeledText); 474 return labeledText.contains(text); 475 } 476 477 protected boolean isLabeledInputTextPresent(String label, String text) { 478 String labeledText = "no input or select found no text returned"; 479 List<WebElement> inputs = getDriver().findElements(By.xpath("//tr/th/label[contains(text(), '" + label + "')]/ancestor::tr/td/div/input")); 480 481 if (inputs.size() > 1) { 482 System.out.println("found more elements in labeled input than expected"); 483 } 484 485 if (inputs.size() == 1) { 486 labeledText = inputs.get(0).getAttribute("value").trim(); 487 // seeing this on Agenda Context select, value is getting uppercased somewhere... 488 if (labeledText.equals(text.toUpperCase())) { 489 text = text.toUpperCase(); 490 } 491 492 } else { 493 inputs = getDriver().findElements(By.xpath("//tr/th/label[contains(text(), '" + label + "')]/ancestor::tr/td/div/select")); 494 495 if (inputs.size() > 1) { 496 System.out.println("found more elements in labeled input than expected"); 497 } 498 499 if (inputs.size() == 1) { 500 List<WebElement> options = inputs.get(0).findElements(By.tagName("option")); 501 for (WebElement option : options) { 502 if (option.getAttribute("selected") != null) { 503 labeledText = option.getText().trim(); 504 } 505 } 506 } 507 } 508 509 WebDriverUtils.jGrowl(getDriver(), "Is Labeled Text Present", false, "Is text '" + text + "' present for label '" 510 + label + "'? " + labeledText.contains(text) + " saw " + labeledText); 511 return labeledText.contains(text); 512 } 513 514 protected boolean isVisible(String locator) { 515 return isVisible(By.cssSelector(locator)); 516 } 517 518 protected boolean isVisible(By by) { 519 List<WebElement> elements = getDriver().findElements(by); 520 for (WebElement element: elements) { 521 try { 522 if (element.isDisplayed()) { 523 return true; 524 } 525 } catch (Throwable t) { 526 // don't fail 527 } 528 } 529 return false; 530 } 531 532 protected boolean isVisibleById(String id) { 533 return isVisible(By.id(id)); 534 } 535 536 protected boolean isVisibleByXpath(String locator) { 537 return isVisible(By.xpath(locator)); 538 } 539 540 protected WebElement jiraAwareClearType(By by, String text) { 541 return jiraAwareClearAndType(by, text, this.getClass().toString().replace("class ", "")); 542 } 543 544 protected WebElement jiraAwareClearAndType(By by, String text, String failureMessage) { 545 findElement(by).clear(); 546 return jiraAwareType(by, text, failureMessage); 547 } 548 549 protected WebElement jiraAwareClearAndTypeByName(String name, String text) { 550 return jiraAwareClearAndType(By.name(name), text, this.getClass().toString().replace("class ", "")); 551 } 552 553 protected WebElement jiraAwareClearAndTypeByName(String name, String text, String failureMessage) { 554 return jiraAwareClearAndType(By.name(name), text, failureMessage); 555 } 556 557 /** 558 * {@inheritDoc} 559 * {@see #checkForIncidentReport} and {@see JiraAwareFailureUtils#fail}. 560 * 561 * @param message to check for a Jira match and fail with. 562 */ 563 @Override 564 public void jiraAwareFail(String message) { 565 jiraAwareFail("", message, null, this); 566 } 567 568 /** 569 * {@inheritDoc} 570 * {@see #checkForIncidentReport} and {@see JiraAwareFailureUtils#fail}. 571 * 572 * @param contents to check for a Jira match 573 * @param message to check for a Jira match and fail with. 574 */ 575 @Override 576 public void jiraAwareFail(String contents, String message) { 577 jiraAwareFail(contents, message, null, this); 578 } 579 580 /** 581 * {@see #checkForIncidentReport} and {@see JiraAwareFailureUtils#fail}. 582 * 583 * @param by to check for a Jira match 584 * @param message to check for a Jira match and fail with. 585 * @param throwable to check for a Jira match 586 */ 587 protected void jiraAwareFail(By by, String message, Throwable throwable) { 588 jiraAwareFail(by.toString(), message, throwable, this); 589 } 590 591 /** 592 * {@inheritDoc} 593 * {@see #checkForIncidentReport} and {@see JiraAwareFailureUtils#fail}. 594 * 595 * @param contents to check for a Jira match 596 * @param message to check for a Jira match and fail with. 597 * @param throwable to check for a Jira match 598 */ 599 @Override 600 public void jiraAwareFail(String contents, String message, Throwable throwable) { 601 jiraAwareFail(contents, message, throwable, this); 602 } 603 604 public void jiraAwareFail(String pageSource, By by, String message, Throwable t) { 605 606 } 607 608 609 /** 610 * {@see #checkForIncidentReport} and {@see JiraAwareFailureUtils#fail}. 611 * 612 * @param contents to check for a Jira match 613 * @param message to check for a Jira match and fail with. 614 * @param throwable to check for a Jira match 615 * @param failable to call fail on 616 */ 617 protected void jiraAwareFail(String contents, String message, Throwable throwable, JiraAwareFailable failable) { 618 passed = false; 619 620 if (message == null) { 621 message = ""; 622 } 623 624 String javascriptErrors = WebDriverUtils.javascriptErrorsToString(WebDriverUtils.javascriptErrors(getDriver())); 625 message = javascriptErrors + message; 626 627 if (contents == null) { 628 contents = getDriver().getPageSource(); 629 } 630 631 if (!contents.startsWith("\nIncident report") && !message.startsWith("\nIncident report")) { 632 String errorMessage = AutomatedFunctionalTestUtils.incidentReportMessage(getDriver().getPageSource(), "", message); 633 if (errorMessage != null) { 634 JiraAwareFailureUtils.failOnMatchedJira(errorMessage, message, failable); 635 JiraAwareFailureUtils.fail(errorMessage, message, throwable, failable); 636 } 637 } 638 639 JiraAwareFailureUtils.fail(contents, message, throwable, failable); 640 } 641 642 /** 643 * {@see #checkForIncidentReport} and {@see JiraAwareFailureUtils#fail}. 644 * 645 * @param by to click on 646 * @param message on failure 647 * @throws InterruptedException 648 */ 649 protected void jiraAwareWaitAndClick(By by, String message) throws InterruptedException { 650 jiraAwareWaitAndClick(by, message, this); 651 } 652 653 protected WebElement jiraAwareType(By by, String text) { 654 return jiraAwareType(by, text, this.getClass().toString().replace("class ", "")); 655 } 656 657 protected WebElement jiraAwareType(By by, String text, String failureMessage) { 658 try { 659 return type(by, text); 660 } catch (Throwable t) { 661 JiraAwareFailureUtils.failOnMatchedJira(by.toString(), failureMessage, this); 662 jiraAwareFail(t.getMessage() 663 + " " 664 + by.toString() 665 + " unable to type text '" 666 + text 667 + "' " 668 + failureMessage 669 + " current url " 670 + getDriver().getCurrentUrl() 671 + "\n" 672 + AutomatedFunctionalTestUtils.deLinespace(getDriver().getPageSource())); 673 } 674 return null; 675 } 676 677 protected WebElement jiraAwareTypeByName(String name, String text) { 678 return jiraAwareType(By.name(name), text, this.getClass().toString().replace("class ", "")); 679 } 680 681 protected WebElement jiraAwareTypeByName(String name, String text, String failureMessage) { 682 return jiraAwareType(By.name(name), text, failureMessage); 683 } 684 685 /** 686 * {@see #jiraAwareWaitFor} 687 * 688 * @param by to click on 689 * @param message on failure 690 * @param failable to fail on if not found 691 * @throws InterruptedException 692 */ 693 protected void jiraAwareWaitAndClick(By by, String message, JiraAwareFailable failable) throws InterruptedException { 694 jiraAwareWaitAndClick(by, WebDriverUtils.configuredImplicityWait(), message, failable); 695 } 696 697 protected void jiraAwareWaitAndClick(By by, int waitSeconds, String message, JiraAwareFailable failable) throws InterruptedException { 698 try { 699 jiraAwareWaitFor(by, waitSeconds, message, failable); 700 findElement(by).click(); 701 // possible future code of outputting clicked components in a more generic way, but need to look into duplicates, don't delete 702 // WebElement element = findElement(by); 703 // String jgrowl = element.getAttribute("name"); 704 // if (jgrowl == null || "".equals(jgrowl)) { 705 // jgrowl = element.getAttribute("id"); 706 // } 707 // if (jgrowl == null || "".equals(jgrowl)) { 708 // jgrowl = by.toString(); 709 // } 710 // WebDriverUtils.jGrowl(getDriver(), "Click " + jgrowl, false, "Click " + jgrowl); 711 // element.click(); 712 } catch (Throwable t) { 713 failable.jiraAwareFail(by.toString(), message, t); 714 } 715 } 716 717 /** 718 * {@see WebDriverUtils#waitFor}. 719 * 720 * @param by to find 721 * @return WebElement found with given by 722 * @throws InterruptedException 723 */ 724 protected WebElement jiraAwareWaitFor(By by) throws InterruptedException { 725 return jiraAwareWaitFor(by, this.getClass().toString()); 726 } 727 728 /** 729 * {@see WebDriverUtils#waitFor}. 730 * 731 * @param by to find 732 * @param message on failure 733 * @return WebElement found with given by 734 * @throws InterruptedException 735 */ 736 protected WebElement jiraAwareWaitFor(By by, String message) throws InterruptedException { 737 try { 738 return WebDriverUtils.waitFor(getDriver(), WebDriverUtils.configuredImplicityWait(), by, message); 739 } catch (Throwable t) { 740 jiraAwareFail(by, message + " " + this.getClass().toString(), t); 741 } 742 return null; // required, but the jiraAwareFail will will end test before this statement is reached 743 } 744 745 /** 746 * {@see WebDriverUtils#waitFor}. 747 * 748 * @param by to find 749 * @param message on failure 750 * @throws InterruptedException 751 */ 752 protected void jiraAwareWaitFors(By by, String message) throws InterruptedException { 753 try { 754 WebDriverUtils.waitFors(getDriver(), WebDriverUtils.configuredImplicityWait(), by, message); 755 } catch (Throwable t) { 756 jiraAwareFail(by, message, t); 757 } 758 } 759 760 /** 761 * {@see WebDriverUtils#waitFor}. 762 * 763 * @param by to find 764 * @param message on failure 765 * @param failable to fail if given by is not found 766 * @throws InterruptedException 767 */ 768 protected void jiraAwareWaitFor(By by, String message, JiraAwareFailable failable) throws InterruptedException { 769 jiraAwareWaitFor(by, WebDriverUtils.configuredImplicityWait(), message, failable); 770 } 771 772 protected void jiraAwareWaitFor(By by, int waitSeconds, String message, JiraAwareFailable failable) throws InterruptedException { 773 try { 774 WebDriverUtils.waitFor(getDriver(), waitSeconds, by, message); 775 } catch (Throwable t) { 776 jiraAwareFail(by.toString(), message, t, failable); 777 } 778 } 779 780 /** 781 * {@see WebDriverUtils#waitFor}. 782 * 783 * @param by to find 784 * @param seconds to wait 785 * @param message on failure 786 * @return WebElement found with given by 787 * @throws InterruptedException 788 */ 789 protected WebElement jiraAwareWaitFor(By by, int seconds, String message) throws InterruptedException { 790 try { 791 return WebDriverUtils.waitFor(getDriver(), seconds, by, message); 792 } catch (Throwable t) { 793 jiraAwareFail(by, message, t); 794 } 795 return null; // required, but the jiraAwareFail will will end test before this statement is reached 796 } 797 798 /** 799 * @return passed 800 */ 801 public boolean isPassed() { 802 return passed; 803 } 804 805 protected void selectOptionByName(String name, String optionValue) throws InterruptedException { 806 selectOption(By.name(name), optionValue); 807 } 808 809 protected void selectOptionByXpath(String locator, String optionValue) throws InterruptedException { 810 selectOption(By.name(locator), optionValue); 811 } 812 813 /** 814 * Uses Selenium's findElements method which does not throw a test exception if not found. 815 * @param by 816 * @param optionValue 817 * @throws InterruptedException 818 */ 819 protected void selectOption(By by, String optionValue) throws InterruptedException { 820 WebElement select1 = findElement(by); 821 List<WebElement> options = select1.findElements(By.tagName("option")); 822 823 String name = select1.getAttribute("name"); 824 825 if (options == null || options.size() == 0) { 826 jiraAwareFail("No options for select " 827 + select1.toString() 828 + " was looking for value " 829 + optionValue 830 + " using " 831 + by.toString()); 832 } 833 834 for (WebElement option : options) { 835 if (option.getAttribute("value").equals(optionValue)) { 836 WebDriverUtils.jGrowl(getDriver(), "Select " + option.getText(), false, "Select " + option.getText() + " from " + name); 837 option.click(); 838 break; 839 } 840 } 841 } 842 843 /** 844 * Uses Selenium's findElements method which does not throw a test exception if not found. 845 * @param by 846 * @param optionText 847 * @throws InterruptedException 848 */ 849 protected void selectOptionText(By by, String optionText) throws InterruptedException { 850 WebElement select1 = findElement(by); 851 List<WebElement> options = select1.findElements(By.tagName("option")); 852 853 String name = select1.getAttribute("name"); 854 855 if (options == null || options.size() == 0) { 856 jiraAwareFail("No options for select " 857 + select1.toString() 858 + " was looking for text " 859 + optionText 860 + " using " 861 + by.toString()); 862 } 863 864 for (WebElement option : options) { 865 if (option.getText().equals(optionText)) { 866 WebDriverUtils.jGrowl(getDriver(), "Select " + option.getText(), false, "Select " + option.getText() + " from " + name); 867 option.click(); 868 break; 869 } 870 } 871 } 872 873 private WebElement type(By by, String text) { 874 WebElement element = findElement(by); 875 String name = element.getAttribute("name"); 876 WebDriverUtils.jGrowl(getDriver(), "Type", false, "Type into " + name + " the text: " + text); 877 WebDriverUtils.highlightElement(getDriver(), element); 878 element.sendKeys(text); 879 return element; 880 } 881 882 private WebElement typeByName(String name, String text) { 883 return type(By.name(name), text); 884 } 885 886 /** 887 * <p> 888 * Set the test state to passed, call jGrowl sticky with success, required to be called at the conclusion of a test 889 * for the saucelabs state of a test to be updated to passed. 890 * </p> 891 */ 892 protected void passed() { 893 if (passed == true) { 894 WebDriverUtils.jGrowl(getDriver(), "Passed has been called more than once " + getClass().getSimpleName(), true, "Passed"); 895 } 896 passed = true; 897 WebDriverUtils.jGrowl(getDriver(), "Success " + getClass().getSimpleName(), true, "Passed"); 898 } 899 900 protected WebElement waitAndType(By by, String text, String message) throws InterruptedException { 901 try { 902 jiraAwareWaitFor(by, message); 903 return type(by, text); 904 } catch (Throwable t) { 905 checkForIncidentReport(by.toString(), message); 906 JiraAwareFailureUtils.failOnMatchedJira(by.toString(), message, this); 907 jiraAwareFail(t.getMessage() 908 + " " 909 + by.toString() 910 + " unable to type text '" 911 + text 912 + "' " 913 + message 914 + " current url " 915 + getDriver().getCurrentUrl() 916 + "\n" 917 + AutomatedFunctionalTestUtils.deLinespace(getDriver().getPageSource())); 918 } 919 return null; 920 } 921}