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