All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cz.datalite.webdriver.components.ZkElement Maven / Gradle / Ivy

Go to download

Integration tests with Selenium 2.0 (WebDriver) - PageObjects pattern (still in beta)

The newest version!
package cz.datalite.webdriver.components;

import cz.datalite.helpers.StringHelper;
import cz.datalite.webdriver.ElementFactory;
import cz.datalite.webdriver.SeleniumUnitTest;
import cz.datalite.webdriver.ZkDriver;
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.*;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.ui.ExpectedConditions;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import static cz.datalite.webdriver.ZkComponents.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 

This is base element for all ZK elements on the page. There are * implemented standard function for find elements as well as static * functions which handles login page, errors, takes screenshot etc.

* * @author Karel Cemus */ public class ZkElement { protected static final Logger LOGGER = LoggerFactory.getLogger( "cz.datalite.selenium" ); /** The Web driver for a test. This is used to call support methods etc. */ protected static ZkDriver zkDriver; /** The web element instance (aka client component counterpart). */ protected WebElement webElement; /** Tree structure of components (emulate sever object tree). */ protected ZkElement parent; /** * Returns the driver assiciated with this element. * * @return the driver */ public static ZkDriver getZkDriver() { return zkDriver; } public static void setZkDriver( final ZkDriver driver ) { zkDriver = driver; } /** *

Waits until component specified by By is not shown or timeout exceed.

* @param by How to find component */ protected static WebElement waitUntilShown(final By by) { return zkDriver.getWebDriverWait().until( ExpectedConditions.visibilityOfElementLocated(by) ); } /** *

Finds element and returns it without wrapping with ZkElement. * This element has no parent so it is looked up in whole page * and it is not waiting til element is shown.

* *

If the component is not found then the * {@link org.openqa.selenium.NoSuchElementException} * is thrown.

* * @param by how to find it * @return unwrapped found element */ public static WebElement findElement( final By by ) { return findElement( by, null ); } /** *

Finds element and returns it without wrapping with ZkElement. * It is not waiting til element is shown.

* *

If the component is not found then the * {@link org.openqa.selenium.NoSuchElementException} * is thrown.

* @param by how to find it * @param contextElement content element - in this subtree will be searched * @return found component. */ public static WebElement findElement( final By by, final ZkElement contextElement ) { return findElement( by, contextElement, false ); } /** *

Finds element and returns it without wrapping with ZkElement. * This element has parent and it is not waiting til element is shown. * Some types of searching requires new looking query after first one and * the second criteria is defined as third parameter

* *

If the component is not found then the * {@link org.openqa.selenium.NoSuchElementException} * is thrown.

* @param by how to find parent * @param contextElement parent of first component * @param childBy how to find child * @return found component. */ public static WebElement findElement( final By by, final ZkElement contextElement, final By childBy ) { return findElement( by, contextElement, false, childBy ); } /** *

Finds element with defined parent and criteria and specifies if the * test has to wait til the component is shown or not. This waiting can * be interrupted by timeout exceeding.

* *

If the component is not found then the * {@link org.openqa.selenium.NoSuchElementException} * is thrown.

* @param by criterion * @param contextElement parent * @param wait wait til component is shown * @return found component. */ public static WebElement findElement( final By by, final ZkElement contextElement, final boolean wait ) { return findElement( by, contextElement, wait, null ); } /** *

Finds element with defined parent and criteria and specifies if the * test has to wait til the component is shown or not. This waiting can * be interrupted by timeout exceeding.Some types of searching requires * new looking query after first one and the second criteria is defined * as third parameter.

* *

If the component is not found then the * {@link org.openqa.selenium.NoSuchElementException} is thrown.

* * @param by criterion * @param contextElement parent * @param wait wait til component is shown * @param childBy how to find child * @return found component. */ public static WebElement findElement( final By by, final ZkElement contextElement, final boolean wait, final By childBy ) { if ( wait ) { waitUntilShown( by ); } return find( by, contextElement, childBy ); } /** *

Main searching function which finds unwrapped elements by * given criteria.

* *

If the component is not found then the * {@link org.openqa.selenium.NoSuchElementException} is thrown.

* * @param by criterion * @param contextElement parent * @param childBy criterion fow child if it is required. * @return the element */ public static WebElement find( final By by, final ZkElement contextElement, final By childBy ) { WebElement element; if ( contextElement == null ) { element = zkDriver.getWebDriver().findElement( by ); } else { element = contextElement.getWebElement().findElement( by ); } if ( by instanceof cz.datalite.webdriver.By && childBy != null ) { final cz.datalite.webdriver.By dlBy = ( cz.datalite.webdriver.By ) by; if ( dlBy.isLookForChild() ) { element = element.findElement( childBy ); } } return element; } /** * Finds all elements which meet given criteria * @param by criteria * @param contextElement parent of elements in DOM * @return list of found unwrapped elements */ public static List findElements( final By by, final ZkElement contextElement ) { if ( contextElement == null ) { return zkDriver.getWebDriver().findElements( by ); } else { return contextElement.getWebElement().findElements( by ); } } /** * Returns first window on the page * @return first window */ public static Window findWindow() { return findWindow( WINDOW.getBy() ); } /** * Returns first window which meets requirements * @param by requirements * @return window element */ public static Window findWindow( final By by ) { return findWindow( by, true ); } /** *

Finds first windows on the page and has option * if to wait til window appears or not. It can * throw {@link org.openqa.selenium.NoSuchElementException} * * @param by criteria * @param wait if wait til component appears * @return found component */ public static Window findWindow( final By by, final boolean wait ) { try { return new Window( null, findElement( by, null, wait ) ); } catch ( Exception ex ) { throw new NoSuchElementException( "Window looked up by: '" + by.toString() + "' wasn't found." ); } } /** * Takes screenshot of actual visible window in browser. It is useful * when the application throws and error to screen it and then add to * report. * * @return screenshot url */ public static String takeScreenshot() { if ( zkDriver.getWebDriver() instanceof TakesScreenshot ) { try { final TakesScreenshot driver = ( TakesScreenshot ) zkDriver.getWebDriver(); final File f = driver.getScreenshotAs( OutputType.FILE ); final File screenshot = new File( zkDriver.getScreenshotDir(), SeleniumUnitTest.getActualTestName() + ".png" ); FileUtils.copyFile( f, screenshot ); LOGGER.debug( "Screenshot taken. File location is '{}'.", screenshot.getAbsolutePath() ); return zkDriver.getScreenshotUrl() + screenshot.getName(); } catch ( IOException ex ) { throw new RuntimeException( ex ); } } else { return ""; } } /** * Looks at the page and decides if the error is shown. In that case * the call stack is read and composed to report, screenshot is taken * and then is thrown exception. */ public static void handleError() { try { zkDriver.waitForProcessing(); final Window errorWin = findWindow( By.className( "error-window" ), false ); errorWin.findButton( By.className( "error-window-show" ) ).click(); zkDriver.waitForProcessing(); zkDriver.sleep( 1000 ); final WebElement element = (( ZkElement ) errorWin.find( By.className( "error-window-details" ) )).getWebElement(); final StringBuilder errorText = new StringBuilder( "Test failed:\n" ); if ( zkDriver.isScreenOnError() ) { // if it is enabled then take screenshot errorText.append( "\nScreenshot is available at " ).append( takeScreenshot() ).append( " \n\n" ); } for ( WebElement popis : element.findElements( By.tagName( "span" ) ) ) { final String text = popis.getText(); if ( !StringHelper.isNull( text ) ) { errorText.append( text ).append( "\n" ); } } throw new IllegalStateException( errorText.toString() ); } catch ( NoSuchElementException e ) { // ok, no error } } /** * After login there is looked for error window which says that * login failed. In this case exception is thrown. */ public static void handleLoginError() { try { zkDriver.waitForProcessing(); findWindow( By.className( "login-error" ), false ); zkDriver.waitForProcessing(); final StringBuilder message = new StringBuilder( 200 ); message.append( "Login failed." ); if ( zkDriver.isScreenOnError() ) { // if it is enabled then take screenshot message.append( "\n\nScreenshot is available at " ).append( takeScreenshot() ).append( " .\n\n" ); } throw new IllegalStateException( message.toString() ); } catch ( NoSuchElementException e ) { // ok, no error } } /** * Tries to find login window and fill it according to configuration. * It is not found then nothing. */ public static void tryLogin() { try { zkDriver.waitForProcessing(); final Window window = findWindow( By.className( "login-window" ), false ); final Textbox username = window.find( By.className( "login-username" ) ); username.write( zkDriver.getUsername() ); final Textbox password = window.find( By.className( "login-password" ) ); password.write( zkDriver.getPassword() ); window.findButton( By.className( "login-submit" ) ).click(); handleLoginError(); } catch ( NoSuchElementException e ) { // Ok, login window not found or bad formated } } /** * Sends special javascript event which should emulate doubleclick. * It is dependent on browser. * @param element target element */ protected static void doubleClickOn( final WebElement element ) { new Actions(zkDriver.getWebDriver()).doubleClick(element).perform(); // if ( zkDriver.getWebDriver() instanceof InternetExplorerDriver ) {// This works for IE driver // zkDriver.executeScript( "arguments[0].fireEvent('ondblclick')", element ); // zkDriver.waitForProcessing(); // } else { // For the FirefoxDriver and 'ChromeDriver': // zkDriver.executeScript( // "var evt = document.createEvent('MouseEvents'); evt.initMouseEvent('dblclick'," // + "true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0," // + "null); " // + "arguments[0].dispatchEvent(evt);", element ); // } } /** * Create new element with it's client widget countepart represented by webElement. * * @param parent parent (component tree structure) * @param webElement the client element. */ public ZkElement( final ZkElement parent, final WebElement webElement ) { this.parent = parent; this.webElement = webElement; } /** * Returns parent component (component tree structure). * * @return component parent or null if tree root. */ public ZkElement getParent() { return parent; } public WebElement getWebElement() { return webElement; } /** * Traverse component tree up and finds parent window. * * @return parent window * @throws IllegalStateException if not found */ public Window getWindow() { if ( parent == null ) { throw new IllegalStateException( "Parent window component not found. This component has no parent." ); } else { return parent.getWindow(); // overwritten in Window } } /** * Finds element with this parent and given criterion. * @param expected type - is ignored, type is determined by css class. * If there was expected wrong class then there would be thrown * ClassCastException * @param by criterion * @return found element derived from ZkElement */ @SuppressWarnings("unchecked") public T find( final By by ) { return ( T ) ElementFactory.create( findElement( by, this ), this ); } /** * Finds all elements with this parent and given criterion. * @param expected type - is ignored, type is determined by css class. * If there was expected wrong class then there would be thrown * ClassCastException * @param by criterion * @return found element derived from ZkElement */ @SuppressWarnings("unchecked") public List findAll( final By by ) { final List webElements = findElements( by, this ); final List elements = new ArrayList( webElements.size() ); for ( WebElement element : webElements ) { final T zkElement = ( T ) ElementFactory.create( element, this ); elements.add( zkElement ); } return elements; } public Button findButton( final By by ) { if ( by.toString().contains( "By.label" ) ) { // looking up by button label in form final String label = by.toString().substring( 10 ); return new Button( this, findElement( By.xpath( ".//button[text()='" + label + "']" ), this ) ); } else { return new Button( this, findElement( by, this, BUTTON.getBy() ) ); } } // ToDo Not implemented yet // public ToolbarButton findToolbarButton( String label ) { // WebElement labelElement = findElement( By.xpath(".//div[contains(@class, 'z-toolbarbutton')]/div/div[text()='" + label + "']/../.."), this); // return new ToolbarButton( this, labelElement ); // } public Checkbox findCheckbox( final By by ) { return new Checkbox( this, findElement( by, this, CHECKBOX.getBy() ) ); } public Datebox findDatebox() { return findDatebox( DATEBOX.getBy() ); } public Datebox findDatebox( final By by ) { return new Datebox( this, findElement( by, this, DATEBOX.getBy() ) ); } public Decimalbox findDecimalbox() { return findDecimalbox( DECIMALBOX.getBy() ); } public Decimalbox findDecimalbox( final By by ) { return new Decimalbox( this, findElement( by, this, DECIMALBOX.getBy() ) ); } public Doublebox findDoublebox() { return findDoublebox( DOUBLEBOX.getBy() ); } public Doublebox findDoublebox( final By by ) { return new Doublebox( this, findElement( by, this, DOUBLEBOX.getBy() ) ); } public Intbox findIntbox() { return findIntbox( INTBOX.getBy() ); } public Intbox findIntbox( final By by ) { return new Intbox( this, findElement( by, this, INTBOX.getBy() ) ); } public Grid findGrid() { return findGrid( GRID.getBy() ); } public Grid findGrid( final By by ) { return new Grid( this, findElement( by, this, GRID.getBy() ) ); } public Listbox findListbox() { final List listboxes = findElements( LISTBOX.getBy(), this ); for ( WebElement element : listboxes ) { if ( element.isDisplayed() ) { return new Listbox( this, element ); } } throw new NoSuchElementException( "Window doesn't contain any visible listbox." ); } public Listbox findListbox( final By by ) { return new Listbox( this, findElement( by, this, LISTBOX.getBy() ) ); } public Set findListboxes() { final List elements = findElements( LISTBOX.getBy(), this ); final Set listboxes = new HashSet(); for ( WebElement element : elements ) { if ( element.isDisplayed() ) { listboxes.add( new Listbox( this, element ) ); } } return listboxes; } // ToDo Not implemented yet // public Tree findTree( final By by ) { // return new Tree( this, findElement( by, this, TREE.getBy() ) ); // } public Lovbox findLovbox() { return findLovbox( LOVBOX.getBy() ); } public Lovbox findLovbox( final By by ) { return new Lovbox( this, findElement( by, this, LOVBOX.getBy() ) ); } public Textbox findTextbox() { return findTextbox( TEXTBOX.getBy() ); } public Textbox findTextbox( final By by ) { return new Textbox( this, findElement( by, this, TEXTBOX.getBy() ) ); } /** * Returns if the element is shown or not. Invisible elements don't * support some methods. * @return if the element is displayed */ public boolean isVisible() { return webElement.isDisplayed(); } @Override public int hashCode() { return webElement.hashCode(); } @Override public boolean equals( final Object obj ) { return webElement.equals( obj ); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy