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

com.seleniumtests.webelements.HtmlElement Maven / Gradle / Ivy

There is a newer version: 4.23.18
Show newest version
/*
 * Copyright 2015 www.seleniumtests.com
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.seleniumtests.webelements;

import static java.util.concurrent.TimeUnit.MILLISECONDS;

import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.log4j.Logger;
import org.openqa.selenium.By;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.ElementNotVisibleException;
import org.openqa.selenium.InvalidElementStateException;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.NoAlertPresentException;
import org.openqa.selenium.Point;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.MarionetteDriver;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.HasInputDevices;
import org.openqa.selenium.interactions.Mouse;
import org.openqa.selenium.internal.Locatable;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.SystemClock;
import org.openqa.selenium.support.ui.WebDriverWait;

import com.seleniumtests.core.SeleniumTestsContextManager;
import com.seleniumtests.core.TestLogging;
import com.seleniumtests.driver.BrowserType;
import com.seleniumtests.driver.CustomEventFiringWebDriver;
import com.seleniumtests.driver.ScreenshotUtil;
import com.seleniumtests.driver.WebUIDriver;
import com.seleniumtests.helper.ContextHelper;
import com.seleniumtests.helper.WaitHelper;
import com.thoughtworks.selenium.webdriven.JavascriptLibrary;


/**
 * Provides methods to interact with a web page. All HTML element (ButtonElement, LinkElement, TextFieldElement, etc.)
 * extends from this class.
 */
public class HtmlElement {

    protected static final Logger logger = TestLogging.getLogger(
            HtmlElement.class);


    protected WebDriver driver = WebUIDriver.getWebDriver();
    protected WebElement element = null;
    private String label = null;
    private HtmlElement parent = null;
    private static SystemClock clock = new SystemClock();
    private int elementIndex = -1;
    private By by = null;

    /**
     * Find element using BY locator. Make sure to initialize the driver before calling findElement()
     *
     * @param   label  - element name for logging
     * @param   by     - By type
     *
     * @sample  {@code new HtmlElement("UserId", By.id(userid))}
     */
    
    public HtmlElement(final String label, final By by) {
    	this(label, by, -1);
    }
    
    /**
     * Find element using BY locator. 
     *
     * @param   label  - element name for logging
     * @param   by     - By type
     * @param	index  - index of the element to find. In this case, robot will search the Nth element corresponding to
     * 					 the By parameter. Equivalent to new HtmlElement(label, by).findElements().get(N)
     *
     * @sample  {@code new HtmlElement("UserId", By.id(userid), 2)}
     */
    public HtmlElement(final String label, final By by, final int index) {
        this.label = label;
        this.by = by;
        this.elementIndex = index;
    }
    
    public HtmlElement(final String label, final By by, final HtmlElement parent) {
    	this(label, by, parent, -1);
    }
    
    public HtmlElement(final String label, final By by, final HtmlElement parent, final int index) {
    	this.label = label;
    	this.by = by;
    	this.parent = parent;
    	this.elementIndex = index;
    }

    /**
     * Captures snapshot of the current browser window.
     */
    public void captureSnapshot() {
        captureSnapshot(ContextHelper.getCallerMethod() + " on ");
    }

    /**
     * Captures snapshot of the current browser window, and prefix the file name with the assigned string.
     *
     * @param  messagePrefix
     */
    protected void captureSnapshot(final String messagePrefix) {
        ScreenshotUtil.captureSnapshot(messagePrefix);
    }

    public void click() {
        findElement();
        element.click();
        
    }

    /**
     * Click element in native way by Actions.
     */
    public void clickAt() {
        clickAt("1,1");

    }

    /**
     * Click element in native way by Actions.
     *
     * 

*

       clickAt("1, 1");
     * 
* * @param value */ public void clickAt(final String value) { TestLogging.logWebStep(null, "click on " + toHTML(), false); findElement(); String[] parts = value.split(","); int xOffset = Integer.parseInt(parts[0]); int yOffset = Integer.parseInt(parts[1]); try { new Actions(driver).moveToElement(element, xOffset, yOffset).click() .perform(); } catch (InvalidElementStateException e) { e.printStackTrace(); element.click(); } try { BrowserType type = WebUIDriver.getWebUIDriver().getConfig() .getBrowser(); if (((type == BrowserType.Chrome) || (type == BrowserType.InternetExplore)) && driver.switchTo().alert().getText().contains( "leave")) { driver.switchTo().alert().accept(); } } catch (NoAlertPresentException e) { e.printStackTrace(); } } public void simulateClick() { findElement(); String mouseOverScript = "if(document.createEvent){var evObj = document.createEvent('MouseEvents');evObj.initEvent('mouseover', true, false); arguments[0].dispatchEvent(evObj);} else if(document.createEventObject) { arguments[0].fireEvent('onmouseover');}"; JavascriptExecutor js = (JavascriptExecutor) driver; js.executeScript(mouseOverScript, element); WaitHelper.waitForSeconds(2); String clickScript = "if(document.createEvent){var evObj = document.createEvent('MouseEvents');evObj.initEvent('click', true, false); arguments[0].dispatchEvent(evObj);} else if(document.createEventObject) { arguments[0].fireEvent('onclick');}"; js.executeScript(clickScript, element); WaitHelper.waitForSeconds(2); } public void simulateSendKeys(CharSequence... keysToSend) { findElement(); // click on element before sending keys through keyboard element.click(); JavascriptExecutor js = (JavascriptExecutor) driver; js.executeScript("arguments[0].focus();", element); if (((CustomEventFiringWebDriver)driver).getWebDriver() instanceof MarionetteDriver) { logger.warn("using specific Marionette method"); js.executeScript(String.format("arguments[0].value='%s';", keysToSend[0].toString()), element); } else { // use keyboard to type ((CustomEventFiringWebDriver)driver).getKeyboard().sendKeys(keysToSend); } } public void simulateMoveToElement(final int x, final int y) { findElement(); ((JavascriptExecutor) driver).executeScript( "function simulate(f,c,d,e){var b,a=null;for(b in eventMatchers)if(eventMatchers[b].test(c)){a=b;break}if(!a)return!1;document.createEvent?(b=document.createEvent(a),a==\"HTMLEvents\"?b.initEvent(c,!0,!0):b.initMouseEvent(c,!0,!0,document.defaultView,0,d,e,d,e,!1,!1,!1,!1,0,null),f.dispatchEvent(b)):(a=document.createEventObject(),a.detail=0,a.screenX=d,a.screenY=e,a.clientX=d,a.clientY=e,a.ctrlKey=!1,a.altKey=!1,a.shiftKey=!1,a.metaKey=!1,a.button=1,f.fireEvent(\"on\"+c,a));return!0} var eventMatchers={HTMLEvents:/^(?:load|unload|abort|errorLogger|select|change|submit|reset|focus|blur|resize|scroll)$/,MouseEvents:/^(?:click|dblclick|mouse(?:down|up|over|move|out))$/}; " + "simulate(arguments[0],\"mousemove\",arguments[1],arguments[2]);", element, x, y); } /** * Find elements inside this element * @param by */ public List findElements(By by) { // find the root element findElement(); return element.findElements(by); } /** * Find an element inside an other one * @param by * @return */ public HtmlElement findElement(By by) { return new HtmlElement(label, by, this); } /** * Find the Nth element inside an other one * Equivalent to HtmlElement("", By.id("0").findElements(By.id("1")).get(0); * except that any action on the found element will be retried if it fails * @param by locator of the element list * @param index index in the list to get * @return */ public HtmlElement findElement(By by, int index) { return new HtmlElement(label, by, this, index); } /** * Finds the element using By type. Implicit Waits is built in createWebDriver() in WebUIDriver to handle dynamic * element problem. This method is invoked before all the basic operations like click, sendKeys, getText, etc. Use * waitForPresent to use Explicit Waits to deal with special element which needs long time to present. */ protected void findElement() { // if a parent is defined, search for it before getting the sub element if (parent != null) { parent.findElement(); if (elementIndex < 0) { element = parent.element.findElement(by); } else { element = parent.element.findElements(by).get(elementIndex); } } else { driver = WebUIDriver.getWebDriver(); if (elementIndex < 0) { element = driver.findElement(by); } else { element = driver.findElements(by).get(elementIndex); } } makeWebElementVisible(element); } private void changeCssAttribute(WebElement element, String cssProperty, String cssPropertyValue) { String javascript = "arguments[0].style." + cssProperty + "='" + cssPropertyValue + "';"; ((JavascriptExecutor) driver).executeScript(javascript, element); } /** * Make element visible. Sometimes useful when real elements are backed by an image element */ private void makeWebElementVisible(WebElement element) { if (SeleniumTestsContextManager.isWebTest()) { try { if (element.getLocation().x < 0) { changeCssAttribute(element, "left", "20px"); changeCssAttribute(element, "position", "fixed"); } if (element.getAttribute("style").toLowerCase().replace(" ", "").contains("display:none")) { changeCssAttribute(element, "display", "block"); } // wait for element to be displayed try { new WebDriverWait(driver, 1).until(ExpectedConditions.visibilityOf(element)); } catch (ElementNotVisibleException e) { TestLogging.logInfo(String.format("element %s not visible", element)); } } catch (Exception e) {} } } /** * Fires a Javascript event on the underlying element. * * @param eventName */ public void fireEvent(final String eventName) { findElement(); try { JavascriptLibrary jsLib = new JavascriptLibrary(); jsLib.callEmbeddedSelenium(driver, "doFireEvent", element, eventName); } catch (Exception ex) { // Handle OperaDriver } } /** * Get all elements in the current page with same locator. * * @return */ public List findElements() { findElement(); return driver.findElements(by); } /** * Gets an attribute (using standard key-value pair) from the underlying attribute. * * @param name * * @return */ public String getAttribute(final String name) { findElement(); return element.getAttribute(name); } /** * Returns the BY locator stored in the HtmlElement. * * @return */ public By getBy() { return by; } /** * Returns the value for the specified CSS key. * * @param propertyName * * @return */ public String getCssValue(final String propertyName) { findElement(); return element.getCssValue(propertyName); } /** * Get and refresh underlying WebDriver. */ protected WebDriver getDriver() { return WebUIDriver.getWebDriver(); } public void setDriver(WebDriver driver) { this.driver = driver; } /** * Returns the underlying WebDriver WebElement. * * @return */ public WebElement getElement() { element = driver.findElement(by); return element; } /** * Executes the given JavaScript against the underlying WebElement. * * @param script * * @return */ public String getEval(final String script) { findElement(); String name = (String) ((JavascriptExecutor) driver).executeScript( script, element); return name; } /** * Returns the 'height' property of the underlying WebElement's Dimension. * * @return */ public int getHeight() { findElement(); return element.getSize().getHeight(); } /** * Returns the label used during initialization. * * @return */ public String getLabel() { return label; } /** * Gets the Point location of the underlying WebElement. * * @return */ public Point getLocation() { findElement(); return element.getLocation(); } /** * Returns the Dimension property of the underlying WebElement. * * @return */ public Dimension getSize() { findElement(); return element.getSize(); } /** * Returns the HTML Tag for the underlying WebElement (div, a, input, etc). * * @return */ public String getTagName() { findElement(); return element.getTagName(); } /** * Returns the text body of the underlying WebElement. * * @return */ public String getText() { findElement(); return element.getText(); } /** * Returns the 'value' attribute of the underlying WebElement. * * @return */ public String getValue() { findElement(); return element.getAttribute("value"); } /** * Returns the 'width' property of the underlying WebElement's Dimension. * * @return */ public int getWidth() { findElement(); return element.getSize().getWidth(); } /** * Refreshes the WebUIDriver before locating the element, to ensure we have the current version (useful for when the * state of an element has changed via an AJAX or non-page-turn action). */ public void init() { driver = WebUIDriver.getWebDriver(); element = driver.findElement(by); } /** * Indicates whether or not the web element is currently displayed in the browser. * * @return */ public boolean isDisplayed() { try { findElement(); return element.isDisplayed(); } catch (Exception e) { return false; } } /** * Searches for the element using the BY locator, and indicates whether or not it exists in the page. This can be * used to look for hidden objects, whereas isDisplayed() only looks for things that are visible to the user * * @return */ public boolean isElementPresent(int timeout) { try { waitForPresent(timeout); return true; } catch (TimeoutException e) { return false; } } public boolean isElementPresent() { return isElementPresent(WebUIDriver.getWebUIDriver().getExplicitWait()); } /** * Indicates whether or not the element is enabled in the browser. * * @return */ public boolean isEnabled() { findElement(); return element.isEnabled(); } /** * Indicates whether or not the element is selected in the browser. * * @return */ public boolean isSelected() { findElement(); return element.isSelected(); } /** * Whether or not the indicated text is contained in the element's getText() attribute. * * @param text * * @return */ public boolean isTextPresent(final String text) { findElement(); return element.getText().contains(text); } /** * Forces a mouseDown event on the WebElement. */ public void mouseDown() { TestLogging.log("MouseDown " + this.toString()); findElement(); Mouse mouse = ((HasInputDevices) driver).getMouse(); mouse.mouseDown(null); } /** * Forces a mouseOver event on the WebElement. */ public void mouseOver() { TestLogging.log("MouseOver " + this.toString()); findElement(); // build and perform the mouseOver with Advanced User Interactions API // Actions builder = new Actions(driver); // builder.moveToElement(element).build().perform(); Locatable hoverItem = (Locatable) element; Mouse mouse = ((HasInputDevices) driver).getMouse(); mouse.mouseMove(hoverItem.getCoordinates()); } /** * Forces a mouseOver event on the WebElement using simulate by JavaScript way for some dynamic menu. */ public void simulateMouseOver() { findElement(); String mouseOverScript = "if(document.createEvent){var evObj = document.createEvent('MouseEvents');evObj.initEvent('mouseover', true, false); arguments[0].dispatchEvent(evObj);} else if(document.createEventObject) { arguments[0].fireEvent('onmouseover');}"; JavascriptExecutor js = (JavascriptExecutor) driver; js.executeScript(mouseOverScript, element); } /** * Forces a mouseUp event on the WebElement. */ public void mouseUp() { TestLogging.log("MouseUp " + this.toString()); findElement(); Mouse mouse = ((HasInputDevices) driver).getMouse(); mouse.mouseUp(null); } /** * Sends the indicated CharSequence to the WebElement. * * @param arg0 */ public void sendKeys(final CharSequence arg0) { findElement(); // on mobile and some fields, this throws an exception which prevents going on try { String elType = element.getAttribute("type"); if (elType != null && !elType.equalsIgnoreCase("file")) { element.clear(); } } catch (WebDriverException | NullPointerException e) { element.clear(); } element.sendKeys(arg0); } /** * Method, which should never be used. */ protected void sleep(final int waitTime) throws InterruptedException { Thread.sleep(waitTime); } /** * Returns string matching the pattern * * @param pattern pattern to find in element text or one of its attribute * @param attributeName name of the attribute to look for * @return found string */ public String findPattern(Pattern pattern, String attributeName) { findElement(); String attributeValue = ""; if (attributeName.equals("text")) { attributeValue = element.getText(); } else { attributeValue = element.getAttribute(attributeName); } Matcher matcher = pattern.matcher(attributeValue); if (matcher.matches() && matcher.groupCount() > 0) { return matcher.group(1); } return ""; } /** * Returns URL present in one of the element attributes * @param attributeName attribute name in which we should look at. Give "text" to search in value * @return the found link */ public String findLink(String attributeName) { // link String link = findPattern(Pattern.compile(".*(http://.*?)'\"?.*"), attributeName); if (!link.equals("")) { return link; } // link with simple quotes link = findPattern(Pattern.compile(".*(http://.*?)\"'?.*"), attributeName); if (!link.equals("")) { return link; } // no quotes return findPattern(Pattern.compile(".*(http://.*)"), attributeName); } /** * Converts the Type, Locator and LabelElement attributes of the HtmlElement into a readable and report-friendly * string. * * @return */ public String toHTML() { return getClass().getSimpleName().toLowerCase() + " " + getLabel() + ",: " + getBy().toString() + ""; } /** * Returns a friendly string, representing the HtmlElement's Type, LabelElement and Locator. */ public String toString() { return getClass().getSimpleName().toLowerCase() + " " + getLabel() + ", by={" + getBy().toString() + "}"; } /** * Wait element to present using Explicit Waits with default EXPLICIT_WAIT_TIME_OUT = 15 seconds. */ public void waitForPresent() { waitForPresent(WebUIDriver.getWebUIDriver().getExplicitWait()); } /** * Wait element to present using Explicit Waits with timeout in seconds. This method is used for special element * which needs long time to present. */ public void waitForPresent(final int timeout) { TestLogging.logWebStep(null, "wait for " + this.toString() + " to present.", false); WebDriverWait wait = new WebDriverWait(driver, timeout); wait.until(ExpectedConditions.presenceOfElementLocated(by)); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy